Spring 批量 Bean 放置
Spring Batch Bean Placement
将 bean 加载到作用域上下文中时,bean 的放置会有所不同吗?这是错误还是实例化时间问题?
如果我将 @StepScope 和 @Bean 直接包含在 BatchConfiguration class 中,一切都可以与 StepScope 无缝配合。但是,如果我定义另一个 class,如下所示 "BatchProcessProcessor",并将另一个 class 中的方法标记为带有 StepScope 的 Bean,它无法正确解析。 spring 批处理中的实际症状是 StepScope 未触发并且 bean 作为单例加载。
关于从 BatchConfiguration 中通过构造函数注入加载的另一个 class 提供 @Bean 和 @StepScope 的问题无法正确解析。
格式如上,包含如下:
主批配置class
@Slf4j
@Configuration
@EnableAutoConfiguration
@EnableBatchProcessing
public class BatchConfiguration extends DefaultBatchConfigurer {
private BatchProcessProcessor processor;
@Override
public void setDataSource(DataSource dataSource) {
// override to do not set datasource even if a datasource exist.
// initialize will use a Map based JobRepository (instead of database)
}
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Autwired
public BatchConfiguration(BatchProcessProcessor processor){
this.processor = processor;
}
@Bean
@StepScope
public ListItemReader<String> reader() {
List<String> stringList = new ArrayList<>();
stringList.add("test");
stringList.add("another test");
log.info("LOGGING A BUNCH OF STUFF THIS IS UNIQUE" + String.valueOf(System.currentTimeMillis()));
return new ListItemReader<>(stringList);
}
@Bean
@StepScope
public CustomWriter writer() {
return new CustomWriter();
}
@Bean
public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(step1)
.end()
.build();
}
@Bean
public Step step1() {
return stepBuilderFactory.get("step1")
.<String, String> chunk(10)
.reader(reader())
.processor(processor.processor())
.writer(writer()).build();
}
}
处理器容器class
@Component
public class BatchProcessProcessor {
private MyService service;
@Autowired
BatchProcessProcessor(MyService service){
this.service= service;
}
/**
* Generate processor utilized for processing
* @return StringProcessor for testing
*/
@Bean
@StepScope
public DeploymentProcesser processor() {
return new DeploymentProcessor(service);
}
}
实际处理器
@Slf4j
@Component
public class DeploymentProcesser implements ItemProcessor<Deployment, Model> {
private MyService service;
@Autowired
public DeploymentProcesser(MyService service){
this.service= service;
}
@Override
public Model process(final Deployment deployment) {
log.info(String.format("Processing %s details", deployment.getId()));
Model model = new Model();
model.setId(deployment.getId());
return model;
}
}
据我所知,当 BatchConfiguration 加载时,它应该注入 BatchProcessProcessor 并使用 stepscope 加载 bean,但这似乎不起作用。
正如我之前所说,只需将 @Bean/@StepScope 直接复制粘贴到 BatchConfiguration 中并返回相同的 DeploymentProcessor 就可以完美地工作并且 StepScope 可以解决。
这是生命周期问题吗?
在用 @Component
:
注释的 class 中声明一个 bean 是没有意义的
@Component
public class BatchProcessProcessor {
private MyService service;
@Autowired // This is correct, you can autowire collaborators
public DeploymentProcesser(MyService service){
this.service= service;
}
@Bean // THIS IS NOT CORRECT
@StepScope
public DeploymentProcesser processor() {
return new DeploymentProcessor(service);
}
}
您应该在配置 class 中使用 @Configuration
进行注释。这就是为什么当您在 BatchConfiguration
.
中执行此操作时它会起作用的原因
将 bean 加载到作用域上下文中时,bean 的放置会有所不同吗?这是错误还是实例化时间问题?
如果我将 @StepScope 和 @Bean 直接包含在 BatchConfiguration class 中,一切都可以与 StepScope 无缝配合。但是,如果我定义另一个 class,如下所示 "BatchProcessProcessor",并将另一个 class 中的方法标记为带有 StepScope 的 Bean,它无法正确解析。 spring 批处理中的实际症状是 StepScope 未触发并且 bean 作为单例加载。
关于从 BatchConfiguration 中通过构造函数注入加载的另一个 class 提供 @Bean 和 @StepScope 的问题无法正确解析。
格式如上,包含如下:
主批配置class
@Slf4j
@Configuration
@EnableAutoConfiguration
@EnableBatchProcessing
public class BatchConfiguration extends DefaultBatchConfigurer {
private BatchProcessProcessor processor;
@Override
public void setDataSource(DataSource dataSource) {
// override to do not set datasource even if a datasource exist.
// initialize will use a Map based JobRepository (instead of database)
}
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Autwired
public BatchConfiguration(BatchProcessProcessor processor){
this.processor = processor;
}
@Bean
@StepScope
public ListItemReader<String> reader() {
List<String> stringList = new ArrayList<>();
stringList.add("test");
stringList.add("another test");
log.info("LOGGING A BUNCH OF STUFF THIS IS UNIQUE" + String.valueOf(System.currentTimeMillis()));
return new ListItemReader<>(stringList);
}
@Bean
@StepScope
public CustomWriter writer() {
return new CustomWriter();
}
@Bean
public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(step1)
.end()
.build();
}
@Bean
public Step step1() {
return stepBuilderFactory.get("step1")
.<String, String> chunk(10)
.reader(reader())
.processor(processor.processor())
.writer(writer()).build();
}
}
处理器容器class
@Component
public class BatchProcessProcessor {
private MyService service;
@Autowired
BatchProcessProcessor(MyService service){
this.service= service;
}
/**
* Generate processor utilized for processing
* @return StringProcessor for testing
*/
@Bean
@StepScope
public DeploymentProcesser processor() {
return new DeploymentProcessor(service);
}
}
实际处理器
@Slf4j
@Component
public class DeploymentProcesser implements ItemProcessor<Deployment, Model> {
private MyService service;
@Autowired
public DeploymentProcesser(MyService service){
this.service= service;
}
@Override
public Model process(final Deployment deployment) {
log.info(String.format("Processing %s details", deployment.getId()));
Model model = new Model();
model.setId(deployment.getId());
return model;
}
}
据我所知,当 BatchConfiguration 加载时,它应该注入 BatchProcessProcessor 并使用 stepscope 加载 bean,但这似乎不起作用。
正如我之前所说,只需将 @Bean/@StepScope 直接复制粘贴到 BatchConfiguration 中并返回相同的 DeploymentProcessor 就可以完美地工作并且 StepScope 可以解决。
这是生命周期问题吗?
在用 @Component
:
@Component
public class BatchProcessProcessor {
private MyService service;
@Autowired // This is correct, you can autowire collaborators
public DeploymentProcesser(MyService service){
this.service= service;
}
@Bean // THIS IS NOT CORRECT
@StepScope
public DeploymentProcesser processor() {
return new DeploymentProcessor(service);
}
}
您应该在配置 class 中使用 @Configuration
进行注释。这就是为什么当您在 BatchConfiguration
.