我首先要感谢《SpringBoot编程思想(核心篇)》的作者,写了这么用心的书。书的内容确实如作者所说,对spring要有一定的了解,看起来才不会太费劲。在此,经过九牛二虎之力反复钻研书籍和代码后,从设计思想的层面来描述下自动装配的构思。
名词约定:
配置类:指使用了@Configuration、@Component、@ComponentScan、@Import、@ImportResource、@Bean的类
元标注:指标注使用的标注
种子配置类:SpringApplication.run( XxxxConfiguration.class, args )命令的XxxxConfiguration.class。
自动装配的主要思路是通过一个配置类,然后引入其他的配置类,在递归的作用下,将需要用到的配置类都加载到spring的容器里。
springboot通过是通过这条命令开始:SpringApplication.run( XxxxConfiguration.class, args );
XxxxConfiguration.class是一个配置类,它是未来发展成一个森林的种子。
springboot用解析和读入两个阶段来处理这个配置类:
1、解析阶段。springboot对配置类的标注及元标注进行检查,检查的次序为@ComponentScan、@Import、@ImportResource、@Bean。
(1)@ComponentScan。程序根据@ComponentScan的package路径,找出使用@Component作为标注或者元标注的类(比如:@Service、@Controller)并注册到spring容器。
(2)@Import。程序递归地找出所有元标注@Import,然后对此标注指定的类进行处理 。这个类是ImportSelector、DeferredImportSelector、ImportBeanDefinitionRegistrar其中一个接口的实现类,如果不是,则将其作为@Configuration的配置类递归地解析。
(3)@ImportResource。将ImportedResources指定的配置文件封闭后,存放到ConfigurationClass的importedResources集合里。其实就是通过@ImportResource标注引入xml配置文件,兼容旧版spring的xml年代。
(4)@Bean。解析出当前配置类里使用@Bean标注的方法,并追加到ConfigurationClass的beanMethods集合。
2、读入阶段。将解析阶段产出物注册到spring容器里。第一阶段的产出物是ConfigurationClass类型的集合。
至此,通过种子配置类,装配了必须的配置类到spring容器。在整个解析及读入阶段中,反复使用到AnnotationAttributes接口和AnnotationMetadata接口,它们用作对标注解析,最终实现springboot的自动装配,因此值得多花精力去研究。
通过《SpringBoot编程思想(核心篇)》的介绍,spring对于标注的发展与完善经历了多个版本。我觉得设计者当年提出此构思来代替xml配置已经相当有创新性了,另外通过标注实现引入更多配置类从而最终实现自动装配更是精益求精的结果,这种创新与追求极致的精神值得我们软件设计人员抱以谦虚的态度去学习,鞭策我们在设计过程中不断创新与求精。