本文贴出的众多代码,版本来源为SpringBoot1.5.10,Spring4.3.14,如果两端代码中间有调用关系,可以通过查找上方的中文注释来快速定位
SpringBootStarter自动装配过程
在项目中我们一般使用 @SpringBootApplication 来作为SpringBoot项目的启动类,SpringBoot采用约定大于配置的思想来进行类的注入,使得配置文件大量简化,服务构建更为快捷
那么SpringBoot是如何进行自动装配的呢?根据SpringBoot1.5.10的源码,可以看到 @SpringBootApplication引用了 @SpringBootConfiguration进行配置1
2
3
4
5
6
7
8
9
10
11
12 (ElementType.TYPE)
(RetentionPolicy.RUNTIME)
//允许注入的代码
(excludeFilters = {
(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public SpringBootApplication {
//省略部分内容
}
而 @SpringBootConfiguration接口使用 @Configuration进行修饰1
2
3
4
5
6
7 (ElementType.TYPE)
(RetentionPolicy.RUNTIME)
//允许注入的代码
public SpringBootConfiguration {
}
也就是读取配置文件并进行注入的工作是由Spring的Configuration实现的
复习一下Configuration的实现步骤
IOC容器启动时,作为一个Component参与到其中
1 | (ElementType.TYPE) |
IOC容器生成后,进行再一步的扩展处理
由Spring IOC容器中的 AnnotationConfigApplicationContext或 AnnotationConfigWebApplicationContext高级上下文容器中生成IOC容器后进行修改
AnnotationConfigWebApplicationContext继承GenericApplicationContext再继承AbstractApplicationContext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext, DisposableBean {
//省略部分内容
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
// 在这里对IOC容器进行再一次处理,SpringBoot的自动装配就是在这个步骤里实现
invokeBeanFactoryPostProcessors(beanFactory);
//省略部分代码
}catch (BeansException ex) {
destroyBeans();
cancelRefresh(ex);
throw ex;
}
}
}
//省略部分内容
}
针对IOC容器中的Configuration部分进行再次处理
1 | public abstract class AbstractApplicationContext extends DefaultResourceLoader |
针对IOC容器中的Configuration部分进行再次处理
1 | class PostProcessorRegistrationDelegate { |
处理前的校验和状态锁定
1 | public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, BeanClassLoaderAware { |
对存在Configuration修饰JAVA类的BeanDefinition进行修改
1 | public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, BeanClassLoaderAware { |
这一步我们讲述了自动装配是如何发生的,下面讲一下自动装配发生前,目标类和配置类是如何进行准备的
筛选需要装配的类和配置
再次回到SpringBootApplication,我们看另外一个接口@EnableAutoConfiguration1
2
3
4
5
6
7
8
9"deprecation") (
(ElementType.TYPE)
(RetentionPolicy.RUNTIME)
//目标类
//配置类 (EnableAutoConfigurationImportSelector.class)
public EnableAutoConfiguration {
}
AutoConfigurationPackage,根据配置的路径扫描需要进程自动配置的目标类
1 | (ElementType.TYPE) |
EnableAutoConfigurationImportSelector,用于返回配置类
1 |
|
通过EnableAutoConfigurationImportSelector的父类AutoConfigurationImportSelector看扫描配置了的步骤
1 | public class AutoConfigurationImportSelector |
获取配置的详细代码
1 | public class AutoConfigurationImportSelector |
而这个具体的获取方法是使用的spring的工厂,加载项目路径下的所有spring.factories文件,返回配置类
1 | public abstract class SpringFactoriesLoader { |
至此目标类和目标配置以及准备完毕