Spring加载流程
参考链接:
https://www.yuque.com/snakes/ayqnq6/fyfefu
https://blog.csdn.net/tzs_1041218129/article/details/107587706
https://juejin.im/post/6869407787760222221
Spring加载流程
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
ac.register(AppConfig.class);
//可以注册普通的bean
//ac.register(User.class);
ac.refresh();
ac.getBean(X.class);
@Configuration
@ComponentScan("com.ruisheng")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppConfig {
}
初始化 AnnotatedBeanDefinitionReader
作用:
- 读取spring内部的 唯一的beanFactoryPostProcess 和 5个beanPostProcess。
- ConfigurationClassPostProcessor (Spring内部唯一的beanFactoryPostProcess的实现类)
- AutowiredAnnotationBeanPostProcessor
- CommonAnnotationBeanPostProcessor
- PersistenceAnnotationBeanPostProcessor
- EventListenerMethodProcessor
- DefaultEventListenerFactory
- 提供给程序员注册bd(
ac.register(AppConfig.class);
),一般是用来注册加了@Configuration的类。
源码解析:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
//使用注解配置时需要注入的一些后置处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
初始化 ClassPathBeanDefinitionScanner
作用:
- 程序员能够在外部调用doScan(), 或者 继承该类可以重写scan规则用来动态扫描注解,需要注册到容器。
- spring内部是自己重新new 新的对象来扫描。
主要方法:org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan
(扫描basePackage路径下的文件,把符合条件的类,转成bd。)
执行 register(AppConfig.class)
作用:一般是配置类 AppConfig.class
,也可以是普通的bean,ac.register(User.class);
主要代码:org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean
(解析bean封装为 BeanDefinitionHolder ,注册到 register 中)
执行 refresh()
prepareRefresh();
准备工作包括设置启动时间,是否激活标志位。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
返回一个factory(DefaultListableBeanFactory)
prepareBeanFactory(beanFactory);
准备工厂
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
作用:
- 主要就是扫描包得到类
- 通过匹配规则和排除规则得到合适的类
- 再通过解析这些类,比如配置类去获取所有的解析出来的类
- 将这些扫描解析出来的类,变成bd
源码分析:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
/**
* getBeanFactoryPostProcessors()得到 1.自定义的且没加@Compoment、2.spring内部维护的BeanDefinitionRegistryPostProcessor实现类。
* 1.自定义的并且没加@Compoment注解的BeanFactoryPostProcessors实现类。
* (就是程序员自己写的,并且没有交给spring管理,就是没有加上@Component)
* (这里所谓自定义指手动调用:annotationConfigApplicationContext.addBeanFactoryPostProcessor();)
* 2.得到spring内部的 BeanDefinitionRegistryPostProcessor 实现类
* spring内部只有一个实现类:ConfigurationClassPostProcessor
*/
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
-
执行 BeanDefinitionRegistryPostProcessor
-
postProcessBeanDefinitionRegistry(registry) 由程序员add的
-
postProcessBeanDefinitionRegistry(registry) 有特色(比如排序,优先级等等) 由spring内部和程序员(register,注解)
备注:这里spring内部的有 ConfigurationClassPostProcessor。
-
postProcessBeanDefinitionRegistry(registry) 剩余的子类 由spring内部和程序员(register,注解)
-
所有父方法 postProcessBeanFactory(beanFactory)
-
-
执行 BeanFactoryPostProcessors
- postProcessBeanFactory(beanFactory) 由程序员add的
- postProcessBeanFactory(beanFactory) 有特色(比如排序,优先级等等) 由spring内部和程序员(register,注解)
- postProcessBeanFactory(beanFactory) 剩余的 由spring内部和程序员(register,注解)
备注1:ConfigurationClassPostProcessor 是优先级最高的被执行的processor(实现了PriorityOrdered接口)。
ConfigurationClassPostProcessor 最先被处理的原因:如果程序中有自定义的BeanFactoryPostProcessor,那么这个PostProcessor首先得通过ConfigurationClassPostProcessor被解析出来,然后才能被Spring容器找到并执行。(ConfigurationClassPostProcessor不先执行的话,这个Processor是不会被解析的,不会被解析的话也就不会执行了)。
备注2:在使用mybatis时,一般配置了MapperScannerConfigurer的bean,这个bean就是继承的BeanDefinitionRegistryPostProcessor,所以也是这个地方把扫描的mybatis的接口注册到容器中的。
registerBeanPostProcessors(beanFactory);
注册 BeanPostProcessor 的实现类,即从Spring容器中找出的BeanPostProcessor接口的bean,并设置到BeanFactory的属性中。之后bean被实例化的时候会调用这个BeanPostProcessor。
- 先注册实现PriorityOrdered接口的BeanPostProcessor
- 在注册实现Ordered接口的BeanPostProcessor
- 最后注册普通BeanPostProcessor
为什么要在这里注册呢?不能在前面或后面?????????????????
initMessageSource();
初始化国际化资源
onRefresh();
registerListeners();
finishBeanFactoryInitialization(beanFactory);
完成BeanFactory的bean实例化