简体   繁体   English

Spring Boot批处理加上调度程序

[英]Spring Boot batch plus scheduler

I am new to spring batch so trying to schedule a batch works as a job every 5 seconds using spring boot batch and scheduler but somewhere I am missing something so getting below error.Please help me to solve this error. 我是Spring Batch的新手,因此尝试使用Spring Boot Batch和Scheduler每5秒调度一次批处理工作,但我缺少某些地方,因此出现错误以下。请帮助我解决此错误。

Error:- 错误:-

2017-03-12 02:23:26.614  INFO 8292 --- [pool-1-thread-1] com.spring.test.BatchConfig              : The time is now 02:23:26
2017-03-12 02:23:26.617 ERROR 8292 --- [pool-1-thread-1] o.s.s.s.TaskUtils$LoggingErrorHandler    : Unexpected error occurred in scheduled task.

java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
    at org.springframework.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721)
    at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)
    at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
    at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
    at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
    at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.enhanceFactoryBean(ConfigurationClassEnhancer.java:384)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:292)
    at com.spring.test.BatchConfig$$EnhancerBySpringCGLIB$$dcfce226.job(<generated>)
    at com.spring.test.BatchConfig.reportCurrentTime(BatchConfig.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

application.properties:- application.properties:-

spring.batch.job.enabled=false

spring-config.xml:- spring-config.xml:-

<beans:beans xmlns="http://www.springframework.org/schema/batch"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/batch
           http://www.springframework.org/schema/batch/spring-batch-3.0.xsd">



    <job id="job">
        <step id="step1">
            <tasklet>
                <chunk reader="itemReader" processor="itemProcessor" writer="itemWriter"
                    commit-interval="1" />
            </tasklet>
        </step>
    </job>

    <beans:bean id="itemReader" class="com.spring.test.Reader" />
    <beans:bean id="itemProcessor" class="com.spring.test.Processor" />
    <beans:bean id="itemWriter" class="com.spring.test.Writer" />

</beans:beans>

Application:- 应用:-

@SpringBootApplication
@EnableScheduling
@ComponentScan
@ImportResource("classpath:spring-config.xml")
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class);
    }
}

BatchConfig:- BatchConfig:

@Configuration
@EnableBatchProcessing
@Import({BatchScheduler.class})
public class BatchConfig {

    private static final Logger log = LoggerFactory
            .getLogger(BatchConfig.class);
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat(
            "HH:mm:ss");

    @Autowired
    private SimpleJobLauncher jobLauncher;

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job job() {
        return jobBuilderFactory.get("job")
                .incrementer(new RunIdIncrementer())
                .flow(step1())
                .end()
                .build();
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .<String, String> chunk(1)
                .reader(new Reader())
                .processor(new Processor())
                .writer(new Writer())
                .build();
    }

    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() throws Exception{
        log.info("The time is now {}", dateFormat.format(new Date()));
        JobParameters param = new JobParametersBuilder().addString("JobID",
                String.valueOf(System.currentTimeMillis())).toJobParameters();
        JobExecution execution =  jobLauncher.run(job(), param);
        System.out.println("Job Execution Status: " + execution.getStatus());
    }


}

BatchScheduler:- BatchScheduler:-

@Configuration
@EnableScheduling
public class BatchScheduler {

    @Bean
    public ResourcelessTransactionManager transactionManager() {
        return new ResourcelessTransactionManager();
    }

    @Bean
    public MapJobRepositoryFactoryBean mapJobRepositoryFactory(
            ResourcelessTransactionManager txManager) throws Exception {

        MapJobRepositoryFactoryBean factory = new 
                MapJobRepositoryFactoryBean(txManager);

        factory.afterPropertiesSet();

        return factory;
    }

    @Bean
    public JobRepository jobRepository(
            MapJobRepositoryFactoryBean factory) throws Exception {
        return factory.getObject();
    }

    @Bean
    public SimpleJobLauncher jobLauncher(JobRepository jobRepository) {
        SimpleJobLauncher launcher = new SimpleJobLauncher();
        launcher.setJobRepository(jobRepository);
        return launcher;
    }

}

It is hard to figure out what is actually wrong with your code but it looks like some of your beans do not have no-args constructor. 很难弄清楚代码的实际问题是什么,但是看起来您的某些bean没有no-args构造函数。

Configuring batch with scheduler is relatively simple. 使用调度程序配置批处理相对简单。 I've just downloaded the code from official batch guide and extended it with small amount of my own code. 我刚刚从官方批处理指南中下载了代码,并用少量我自己的代码进行了扩展。

You can try the same: 您可以尝试相同的方法:

1) Add spring.batch.job.enabled=false to application.properties file (just like you already have in your project) 1)将spring.batch.job.enabled=false添加到application.properties文件(就像您已经在项目中一样)

2) Add @EnableScheduling to a Application class (just like you have in your code) 2)将@EnableScheduling添加到Application类(就像您在代码中一样)

3) Create a Component class for scheduling with the next code: 3)使用下面的代码创建一个用于调度的Component类:

import org.springframework.batch.core.*;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class Scheduler {
    @Autowired
    private JobLauncher jobLauncher;
    @Autowired
    private Job job;

    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() throws Exception{
        JobParameters param = new JobParametersBuilder().addString("JobID",
                String.valueOf(System.currentTimeMillis())).toJobParameters();
        JobExecution execution =  jobLauncher.run(job, param);
        System.out.println("Job Execution Status: " + execution.getStatus());
    }
}

That works well. 那很好。 Hope that having this example you'll figure out what is wrong with your own code. 希望有了这个示例,您将弄清楚自己的代码出了什么问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM