春季批处理作业自动运行

huangapple go评论141阅读模式
英文:

Spring batch job runs automatically

问题

我正在使用 Spring Batch 读取 CSV 文件并将其写入数据库,使用控制器触发器。在启动应用程序之前,在我从浏览器 URL 发出请求之前,我可以在启动时从我的读取器中看到打印语句。尽管我的处理器和写入器不会打印出来,它们位于我已经自动装配的不同类中。这是因为读取器是一个 bean 吗?

我在应用程序启动时在日志中看到了来自我的 FlatFileItemReader 的打印语句。但是只有当我访问控制器 URL 时,我的处理器和写入器的打印语句才会显示在控制台中。

我尝试在 application.properties 文件中添加 spring.batch.job.enabled=false,但它无法阻止读取器 bean 的执行。如何防止在 SpringBatchConfig 类中自动执行读取器 bean:

SpringBatchConfig 类:

@Configuration
@EnableBatchProcessing
public class SpringBatchConfig {
	
	// ... 其他自动装配的字段 ...

    @Bean
    public FlatFileItemReader<User> itemReader() {
        // ... 读取器的配置 ...
    }

    @Bean
    public LineMapper<User> lineMapper() {
        // ... 行映射器的配置 ...
    }

    @Bean
    public Step step1() throws Exception {
        return stepBuilderFactory.get("step1")
                .<User, User>chunk(100)
                .reader(itemReader())
                .processor(processor1)
                .writer(writer1)
                .build();
    }

    @Bean
    public Job job() throws Exception {
        return this.jobBuilderFactory.get("BATCH JOB")
                .incrementer(new RunIdIncrementer())
                .start(step1())
                .build();
    }
}

DBWriter 类:

@Component
public class DBWriter implements ItemWriter<User> {
    // ... 写入器的配置 ...
}

Processor 类:

@Component
public class Processor implements ItemProcessor<User, User> {
    // ... 处理器的配置 ...
}

Controller 类:

@RestController
@RequestMapping("/load")
public class LoadController {
    // ... 控制器的配置 ...
}
英文:

I'm using a spring batch to read a CSV file and write it to the DB, using the controller trigger. On starting the application, before I hit from the browser url, I see the print statements from my reader, on the startup. Although it doesn't print it for my processor or writer, which are in separate classes which I have autowired. Is it because the reader is a bean?

I see the print statements from my FlatFileItemReader in the log on the application startup. But the print statements for my processor and writer only show up in the console when I hit the controller url.
I've tried adding spring.batch.job.enabled=false in the application.properties file, but it doesnt stop the execution of the reader bean. How can I prevent auto execution of the reader bean in the SpringBatchConfig class:

SpringBatchConfig class:

@Configuration
@EnableBatchProcessing
public class SpringBatchConfig {
	
	@Autowired
	private JobBuilderFactory jobBuilderFactory;
	
	@Autowired
	private StepBuilderFactory stepBuilderFactory;
	
	@Autowired
	private DataSource dataSource;
	
	@Autowired
	private DBWriter writer1;
	
	@Autowired
	private Processor processor1;
	
	//Step 1 - CSV to DB
    @Bean
    public FlatFileItemReader&lt;User&gt; itemReader() {

        FlatFileItemReader&lt;User&gt; flatFileItemReader = new FlatFileItemReader&lt;&gt;();
        flatFileItemReader.setResource(new FileSystemResource(&quot;src/main/resources/users.csv&quot;));
        flatFileItemReader.setName(&quot;CSV-Reader&quot;);
        flatFileItemReader.setLinesToSkip(1);
        flatFileItemReader.setLineMapper(lineMapper());
        System.out.println(&quot;inside file reader 1 !!!!!&quot;);
        return flatFileItemReader;
    }

    @Bean
    public LineMapper&lt;User&gt; lineMapper() {

        DefaultLineMapper&lt;User&gt; defaultLineMapper = new DefaultLineMapper&lt;&gt;();
        DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();

        lineTokenizer.setDelimiter(&quot;,&quot;);
        lineTokenizer.setStrict(false);
        lineTokenizer.setNames(new String[]{&quot;id&quot;, &quot;name&quot;, &quot;dept&quot;, &quot;salary&quot;});

        BeanWrapperFieldSetMapper&lt;User&gt; fieldSetMapper = new BeanWrapperFieldSetMapper&lt;&gt;();
        fieldSetMapper.setTargetType(User.class);

        defaultLineMapper.setLineTokenizer(lineTokenizer);
        defaultLineMapper.setFieldSetMapper(fieldSetMapper);

        return defaultLineMapper;
    }

    @Bean
    public Step step1() throws Exception{	// Step 1 - Read CSV and Write to DB
    	return stepBuilderFactory.get(&quot;step1&quot;)
    			.&lt;User,User&gt;chunk(100)
    			.reader(itemReader())
    			.processor(processor1)
    			.writer(writer1)
    			.build();
    }

   @Bean
    public Job job() throws Exception{
    	return this.jobBuilderFactory.get(&quot;BATCH JOB&quot;)
    			.incrementer(new RunIdIncrementer())
    			.start(step1())
    			.build();
    }

DBWriter class:

@Component
public class DBWriter implements ItemWriter&lt;User&gt; {

    @Autowired
    private UserRepository userRepository;

    @Override
    public void write(List&lt;? extends User&gt; users) throws Exception {
    System.out.println(&quot;Inside DB Writer&quot;);
        System.out.println(&quot;Data Saved for Users: &quot; + users);
        	userRepository.save(users);
    }
}

Processor class:

@Component
public class Processor implements ItemProcessor&lt;User, User&gt; {

    private static final Map&lt;String, String&gt; DEPT_NAMES =
            new HashMap&lt;&gt;();

    public Processor() {
        DEPT_NAMES.put(&quot;001&quot;, &quot;Technology&quot;);
        DEPT_NAMES.put(&quot;002&quot;, &quot;Operations&quot;);
        DEPT_NAMES.put(&quot;003&quot;, &quot;Accounts&quot;);
    }

    @Override
    public User process(User user) throws Exception {
        String deptCode = user.getDept();
        String dept = DEPT_NAMES.get(deptCode);
        user.setDept(dept);
        user.setTime(new Date());
        System.out.println(String.format(&quot;Converted from [%s] to [%s]&quot;, deptCode, dept));
        return user;
    }
}

Controller Class:

@RestController
@RequestMapping(&quot;/load&quot;)
public class LoadController {

    @Autowired
    JobLauncher jobLauncher;

    @Autowired
    Job job;

    @GetMapping(&quot;/users&quot;)
    public BatchStatus load() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {


        Map&lt;String, JobParameter&gt; maps = new HashMap&lt;&gt;();
        maps.put(&quot;time&quot;, new JobParameter(System.currentTimeMillis()));
        JobParameters parameters = new JobParameters(maps);
        JobExecution jobExecution = jobLauncher.run(job, parameters);

        System.out.println(&quot;JobExecution: &quot; + jobExecution.getStatus());

        System.out.println(&quot;Batch is Running...&quot;);
        while (jobExecution.isRunning()) {
            System.out.println(&quot;...&quot;);
        }

        return jobExecution.getStatus();
    }
}

答案1

得分: 3

spring.batch.job.enabled=false属性用于阻止在应用程序启动时运行作业。

创建阅读器的方法仍将在配置时间调用,因此您会看到打印语句。但这并不意味着阅读器是在运行的作业内部调用的。

英文:

The spring.batch.job.enabled=false property is used to prevent running jobs at application startup.

The method that creates the reader will be still be called at configuration time, so it's normal that you see the print statement. But that does not mean the reader was called inside a running job.

huangapple
  • 本文由 发表于 2020年9月30日 15:34:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/64132910.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定