有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JavaSpring批处理Bean放置

当将bean加载到范围上下文中时,bean的放置是否会产生不同的影响?这是一个bug还是实例化的时间问题

如果我在BatchConfiguration类中直接包含@StepScope和@Bean,那么一切都可以与StepScope无缝地工作。但是,如果我定义了另一个类,比如下面包含的“BatchProcessProcessor”,并将另一个类中的一个方法标记为带有StepScope的Bean,它将无法正确解析。spring批处理中的实际症状是StepScope未触发,bean作为单例加载

关于从另一个类提供@Bean和@StepScope(通过BatchConfiguration中的构造函数注入加载)的某些内容无法正确解析

上述格式,包括以下内容:

主批处理配置类

@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();
    }

}

处理器容器类

@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即可解决问题

这是一个生命周期问题吗


共 (1) 个答案

  1. # 1 楼答案

    在用@Component注释的类中声明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);
       } 
    }
    

    您更应该在用@Configuration注释的配置类中执行此操作。这就是为什么在BatchConfiguration中执行时它会起作用