什么是自动装配?解决了什么问题?
《Spring实战》中给装配的定义是:创建应用对象之间协作关系的行为称为装配。也就是说,当A对象中的属性是B对象的时候,在实例化A时,需要对B进行实例化并将其引用赋值给A对应的属性。
自动装配其实就是依赖注入的升级版本,是为了简化依赖注入的配置而生成的。在传统的依赖注入中,我们必须要明确给属性装配的是哪一个bean的引用,也可以叫做手动装配。在bean很多的情况下,是非常不方便的。
因此,SpringBoot采用注解来进行自动装配。用户不需要知道属性具体要装配哪一个bean,只需要代码中加入注解,剩余的对bean的识别工作交由Spring来完成。也就是说,自动装配就是将依赖注入"自动化"后的一个升级版本。
自动装配的实现原理?
- 当SpringBoot应用程序被启动时,首先会创建一个
SpringApplication
对象。在此对象的构造方法中会完成一系列的参数的初始化工作,最主要是判断当前应用程序的类型,初始化监听器等等。在这个过程中,会加载整个应用程序中的所有的spring.factories文件,将文件的内容放到cache中,方便后续获取。 - 在上述对象创建完成后,开始执行
run()
。run()
里面有两个最关键的方法prepareContext()
和refreshContext()
。 prepareContext()
主要完成了上下文对象context的初始化操作,包括属性值的设置,比如Envirment
对象的设置等等。在prepareContext()
方法中有一个很重要的方法load()
。load()
主要完成了一件事,就是将当前的启动类作为beanDefinition
注册到registry
中,方便后续在BeanFactoryPostProcessor
中调用时,找到对应的主类完成@SpringBootApplication
和@EnableAutoConfiguration
等注解的解析工作。refreshContext()
中会调用Spring的refresh()
方法,来完成整个Spring应用的启动。在自动装配的过程中,会调用invokeBeanFactoryPostProcessor()
方法来对ConfigurationClassPostProcessor
类进行处理,这个类是BeanFactoryPostProcessor
的子类,也是BeanDefinitionRegistryPostProcessor
的子类。处理主要是解析@PropertySource
@ComponentScans
@Bean
@Import
等注解,最重要的@Import
的解析。- 在解析
@Import
时,会从主类开始递归解析注解,把所有包含@Import
的注解都解析到。以此来获取所有需要导入或前置加载的类的全限定类名,然后通过反射的方式将对应的bean装入IOC容器中去。这也就完成了自动装配的核心,也就是@EnableAutoConfiguration
注解。
如果上面有说的不对的地方,欢迎大佬批评指正 O(∩_∩)O