起源于一个@EnableBatchProcessing注解,开启SpringBatch功能。
先看此注解:
注意Import,点进BatchConfigurationSelector一探究竟。
它实现了ImportSelector,作用就是加载其它配置,这里红圈中的是我们需要关注的,加载的SimpleBatchConfiguration配置,上面的ModularBatchConfiguration可以先不看,用的不多。下面重点移到SimpleBatchConfiguration上来。
打开SimpleBatchConfiguration
先看这四部分是干啥的,
第一个ApplicationContext,是用来initialize方法中获取BatchConfigurer的;
第二个初始化标记,后面会用到这个初始化标记,有点不够优雅,后面来分析;
第三个springbatch常用的组件,用AtomicReference来包装,防止并发修改。(有并发的场景?)
第四部分是常用组件的bean配置,两个特性,一个是懒加载,一个是使用上面的AtomicReference防并发修改。
大体看下来,这个SimpleBatchConfiguration最终就是配置了几个组件,然后加载到spring上下文中。
OK,问题来了,这些bean是怎么实例化的?
查看createLazyProxy方法
这个就是创建了一个代理工厂,然后返回一个代理对象。结合下面的代码看,红圈里的需要关注一下。这才是懒加载要调用的地方。
他还搞了个内部类,经过debug验证,红圈中的方法在bean加载的时候不会去调用,当执行job的时候才会去调用。下面关注initialize()方法,这个里面做了很多事。
上文中提到的变量来了,这个变量是第一次调用的时候把所有的组件都初始化好后,然后置成false,保证只被初始化一次,有点Low的感觉。
重点来了:
这一行代码,就是去获取配置类,拿到之后后面几个都能取到值了,说明这里面做了组件的初始化。跟进去看...
AbstractBatchConfiguration类的getConfigurer方法,有一些判断,没有数据源的那个if里不用看了,工作中很少用这个没有数据源的,主要看红圈里有数据源的,里面红圈是重点,再点进去看...
DefaultBatchConfigurer的initialize方法,不过这里用了@PostConstruct会不会被调用两次?
在这里我看看到,通过工厂bean创建了jobRepository,jobExplorer,jobLauncher
最后退回到
初始化的时候initialize把上面的组件塞到AtomicReference,初始化完成后再取出来。其实是在运行时懒加载的bean。