关于java:Purpose of Bean annotations for non-Job methods in trivial Spring Batch example

Purpose of Bean annotations for non-Job methods in trivial Spring Batch example

我正在熟悉整个 Spring 堆栈。

我在这里指的是 spring.io 上发布的一个简单的 Spring Batch 示例:https://spring.io/guides/gs/batch-processing/

作业配置类 BatchConfiguration 中的每个方法都使用 @Bean 进行注释。除了作业方法 importUserJob 之外,注释由创建作业的单例类型 Bean 方法调用的单例类型 Bean 辅助方法有什么意义吗?

在我看来,通过从除 importUserJob 之外的所有方法中删除 @Bean 注释,所有这些代码将仅在每个 Spring 实例中调用一次,并且只能从 importUserJob 方法中调用。

所有 Spring Batch 示例都显示在非作业方法周围的 @Bean 注释中,所以它一定有一些让我无法理解的东西。

以下摘录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
    @Autowired public JobBuilderFactory jobBuilderFactory;
    @Autowired public StepBuilderFactory stepBuilderFactory;
    @Autowired public DataSource dataSource;

    @Bean
    public FlatFileItemReader<Person> reader() ...

    @Bean
    public PersonItemProcessor processor() ...

    @Bean
    public JdbcBatchItemWriter<Person> writer() ...

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

    @Bean
    public Step step1() ...
}

感谢您的阅读和帮助。


@Bean 注释使方法成为bean 创建方法,并且生成的对象将在Spring ApplicationContext 中注册为bean。

因此,它将参与所述上下文的生命周期,并接收像 @PostConstruct 注释的方法将被调用的回调或像 InitializingBean 这样的接口回调。

如果你省略 @Bean 这将不会发生。例如,对于 FlatFileItemReader,这将导致 afterPropertiesSet 方法未被调用,这将导致 bean 未完全初始化。

因此,不应该省略 @Bean,因为 @Bean 相当于 XML 中的 <bean />


从技术上讲,您可以在不使用 @Bean 的情况下为您提到的那些函数编写批处理,并且您的假设是正确的,因为 bean 没有在其他地方使用。 (我自己没有尝试过,但我认为它会运行 - 如果 Spring Batch 不将它们用于其他东西)。

一个 @Bean 注释对象的生命周期由 Spring 处理,因此它可以正确执行依赖注入。这样,您可以将对象的构造与它们的使用 (IoC) 分开。特别是,当您使用自动装配时,依赖注入变得更加容易。

您当然可以手动执行此操作,但这需要大量样板代码,并且您需要发送配置的对象。在您的示例中,为所有内容创建 bean 可能没有任何好处,但是当批次变大时,我相信您会错过 Springs bean 处理的灵活性。我个人用其他一些框架编写了一个没有 Springs 依赖注入的批处理。首先我有一个紧凑的模型,但随着事情的发展,我真的感受到了样板代码的痛苦,这影响了我的代码的可读性。

此外,Spring 管理的 bean 还负责做其他事情,例如关闭资源。

当然,依赖注入只是一种工具,对于某些用例来说可能是一种过度杀伤力。您可能会对这些文章感兴趣:

  • https://martinfowler.com/articles/dipInTheWild.html
  • https://sites.google.com/site/unclebobconsultingllc/blogs-by-robert-martin/dependency-injection-inversion