Job/Step/Reader/Writer 应该都是bean吧?
Should Job/Step/Reader/Writer all be bean?
就 Spring 批处理参考文档中的所有示例而言,我看到像 job/step/reader/writer 这样的对象都被标记为 @bean,如下所示:
@Bean
public Job footballJob() {
return this.jobBuilderFactory.get("footballJob")
.listener(sampleListener())
...
.build();
}
@Bean
public Step sampleStep(PlatformTransactionManager transactionManager) {
return this.stepBuilderFactory.get("sampleStep")
.transactionManager(transactionManager)
.<String, String>chunk(10)
.reader(itemReader())
.writer(itemWriter())
.build();
}
我有一个场景,即服务器端将同时接收请求和 运行 作业(不同的作业名称或具有不同作业参数的相同作业名称)。用法是在并发线程中new一个job对象(包括steps/reader/writers),所以我一般不会把job方法写成@bean,每次new一个job。
而reader在如何将参数传递给对象上实际上是有区别的。如果使用 @bean ,参数必须放在例如使用@StepScope 将 JobParameters 后期绑定到对象中,如下例所示:
@StepScope
@Bean
public FlatFileItemReader flatFileItemReader(@Value(
"#{jobParameters['input.file.name']}") String name) {
return new FlatFileItemReaderBuilder<Foo>()
.name("flatFileItemReader")
.resource(new FileSystemResource(name))
}
如果不使用@bean,我可以直接传参,不需要往JobParameter里放数据,如下
public FlatFileItemReader flatFileItemReader(String name) {
return new FlatFileItemReaderBuilder<Foo>()
.name("flatFileItemReader")
.resource(new FileSystemResource(name))
}
简单的测试表明没有@bean 起作用。但我想正式确认一下:
1、在job/step/reader/writer处使用@bean是不是必须的?
2、如果不是必须的,当我像reader这样new一个对象的时候,需要手动调用afterPropertiesSet()吗?
谢谢!
1、 Is using @bean at job/step/reader/writer mandatory or not ?
不,将批处理工件声明为 beans 不是强制性的。但是您至少希望将 Job
声明为一个 bean,以便从 Spring 的依赖注入中获益(例如将作业存储库引用注入作业等)并能够执行以下操作:
ApplicationContext context = new AnnotationConfigApplicationContext(MyJobConfig.class);
Job job = context.getBean(Job.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
jobLauncher.run(job, new JobParameters());
2、 if it is not mandatory, when I new a object like reader, do I need to call afterPropertiesSet() manually?
我猜想“当我新建一个像 reader 这样的对象时”是指手动创建一个新实例。在这种情况下是的,如果对象不是由 Spring 管理的,则需要自己调用该方法。如果对象声明为 bean,Spring 将调用
afterPropertiesSet()
方法自动。这是一个快速示例:
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TestAfterPropertiesSet {
@Bean
public MyBean myBean() {
return new MyBean();
}
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(TestAfterPropertiesSet.class);
MyBean myBean = context.getBean(MyBean.class);
myBean.sayHello();
}
static class MyBean implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("MyBean.afterPropertiesSet");
}
public void sayHello() {
System.out.println("Hello");
}
}
}
这会打印:
MyBean.afterPropertiesSet
Hello
就 Spring 批处理参考文档中的所有示例而言,我看到像 job/step/reader/writer 这样的对象都被标记为 @bean,如下所示:
@Bean
public Job footballJob() {
return this.jobBuilderFactory.get("footballJob")
.listener(sampleListener())
...
.build();
}
@Bean
public Step sampleStep(PlatformTransactionManager transactionManager) {
return this.stepBuilderFactory.get("sampleStep")
.transactionManager(transactionManager)
.<String, String>chunk(10)
.reader(itemReader())
.writer(itemWriter())
.build();
}
我有一个场景,即服务器端将同时接收请求和 运行 作业(不同的作业名称或具有不同作业参数的相同作业名称)。用法是在并发线程中new一个job对象(包括steps/reader/writers),所以我一般不会把job方法写成@bean,每次new一个job。
而reader在如何将参数传递给对象上实际上是有区别的。如果使用 @bean ,参数必须放在例如使用@StepScope 将 JobParameters 后期绑定到对象中,如下例所示:
@StepScope
@Bean
public FlatFileItemReader flatFileItemReader(@Value(
"#{jobParameters['input.file.name']}") String name) {
return new FlatFileItemReaderBuilder<Foo>()
.name("flatFileItemReader")
.resource(new FileSystemResource(name))
}
如果不使用@bean,我可以直接传参,不需要往JobParameter里放数据,如下
public FlatFileItemReader flatFileItemReader(String name) {
return new FlatFileItemReaderBuilder<Foo>()
.name("flatFileItemReader")
.resource(new FileSystemResource(name))
}
简单的测试表明没有@bean 起作用。但我想正式确认一下:
1、在job/step/reader/writer处使用@bean是不是必须的?
2、如果不是必须的,当我像reader这样new一个对象的时候,需要手动调用afterPropertiesSet()吗?
谢谢!
1、 Is using @bean at job/step/reader/writer mandatory or not ?
不,将批处理工件声明为 beans 不是强制性的。但是您至少希望将 Job
声明为一个 bean,以便从 Spring 的依赖注入中获益(例如将作业存储库引用注入作业等)并能够执行以下操作:
ApplicationContext context = new AnnotationConfigApplicationContext(MyJobConfig.class);
Job job = context.getBean(Job.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
jobLauncher.run(job, new JobParameters());
2、 if it is not mandatory, when I new a object like reader, do I need to call afterPropertiesSet() manually?
我猜想“当我新建一个像 reader 这样的对象时”是指手动创建一个新实例。在这种情况下是的,如果对象不是由 Spring 管理的,则需要自己调用该方法。如果对象声明为 bean,Spring 将调用
afterPropertiesSet()
方法自动。这是一个快速示例:
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TestAfterPropertiesSet {
@Bean
public MyBean myBean() {
return new MyBean();
}
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(TestAfterPropertiesSet.class);
MyBean myBean = context.getBean(MyBean.class);
myBean.sayHello();
}
static class MyBean implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("MyBean.afterPropertiesSet");
}
public void sayHello() {
System.out.println("Hello");
}
}
}
这会打印:
MyBean.afterPropertiesSet
Hello