前言
最近在阅读spring源码,refresh这个方法的处理流程每次看都会有一点新的认识。本文章是自己对这一块源码功能的梳理记录。文章只对这一块代码的主要流程做一个梳理,需要对以下类有一定的认识。
- PropertySources
- BeanFactory
- DefaultListableBeanFactory
- ConfigurableListableBeanFactory
- BeanDefinitionRegistry
- BeanDefinition
- BeanFactoryPostProcessor
- BeanPostProcessor 另外,本文是基于springboot工程启动时梳理的spring的加载过程,有些实现类是springboot提供的。下面放一张类关系图。其中AnnotationConfigServletWebServerApplicationContext和ServletWebServerApplicationContext由springboot提供。
refresh整体结构
下面的代码是从AbstractApplicationContext类中摘下来的,只保留了关键处理流程。Spring启动时会执行这个方法,主要流程就是try代码块中的几个方法。里面的功能包含:
- Ioc容器初始化
- 对扫描到的class进行封装
- bean的实例化、属性填充、初始化、扩展点方法的调用
- AOP包装
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
} catch (BeansException ex) {
destroyBeans();
cancelRefresh(ex);
throw ex;
} finally {
resetCommonCaches();
contextRefresh.end();
}
}
}
流程梳理
1. prepareRefresh
清理scanner的缓存,初始化PropertySources,校验环境中的一些关键属性。
2. obtainFreshBeanFactory
springboot启动时,beanFactory是在refresh执行之前创建的,这里直接返回。
3. prepareBeanFactory(beanFactory)
设置一些ioc容器加载时必须使用的 BeanPostProcessor 和 register。
4. postProcessBeanFactory(beanFactory)
根据我的上下文,是进入AnnotationConfigReactiveWebServerApplicationContext中,啥也没做。
5.invokeBeanFactoryPostProcessors(beanFactory)
- 主要流程
- 调用 BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,扫描class,封装成BeanDefinition。分三次调用,第一次时实现PriorityOrdered接口的,第二次是实现 Ordered 接口的,第三次是其他的所有注册器,例如mybatis的注册器。
- 调用 BeanFactoryPostProcessor的postProcessBeanFactory方法,在bean创建之前,修改bean的定义属性。分三次调用,第一次时实现PriorityOrdered接口的,第二次是实现 Ordered 接口的,第三次是其他的。
- 关键类功能
- ConfigurationClassPostProcessor:从启动类开作为入口,解析 @Configuration 标记的类。扫描出来的class后边会遍历进行处理。
- ClassPathBeanDefinitionScanner:doScan方法干活,把能读取到的class文件中使用了@Component注解的类都封装成BeanDefinition。@Bean注解标记的class,判断scope是否需要创建代理对象。
- ConfigurationClassParser:doProcessConfigurationClass方法解析当前类,把@PropertySource、@ComponentScan、@Import、@ImportResource、@Bean、接口方法、super类方法都进行处理。需要注册的bean统统管理在beanFactory中。
- 扩展点
- @Import、@ImportResource注解。在执行到这两个注解的处理时可以把自定义的对象导入到spring容器中。
- BeanDefinitionRegistryPostProcessor接口。实现类放到spring中之后,spring会调用对应的postProcessBeanDefinitionRegistry,实现自定义对象的注册。
6. registerBeanPostProcessors(beanFactory)
- 主要流程 通过前面的扫描和注册,spring能管理的bean都已经被读取出来了。这里找出实现了BeanPostProcessor接口的类,按优先级排序后注册起来。优先级从高到低依次是实现PriorityOrdered接口的,实现 Ordered 接口的,没优先级和order顺序的,internal的。
7. initMessageSource
国际化处理
8. initApplicationEventMulticaster
初始化一个事件广播器,注册到beanFactory中。
9. onRefresh
- 功能 我们这里分析的是web应用,这里会使用内置的tomcat创建一个webserver。
10. registerListeners
注册listener
11. finishBeanFactoryInitialization(beanFactory)
- 主要流程 实例化非延迟加载的bean实例
- 遍历所有的beanName,通过getBean去创建需要加载的bean。涉及实例化、填充、初始化三个阶段。
- 再遍历所有的beanName,找到SmartInitializingSingleton类型的bean,调用它的afterSingletonsInstantiated方法。
- getBean()处理过程
- Object sharedInstance = getSingleton(beanName); 先获取一次
- markBeanAsCreated(beanName); 放到已经创建的列表,做标记用
- getSingleton(String beanName, ObjectFactory<?> singletonFactory); 再获取一次,没有的话调用singletonFactory.getObject()创建
- createBean(beanName, mbd, args); // 这就是上面的创建具体实现
- doCreateBean(beanName, mbdToUse, args);//真正的创建方法
- populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw); // 这里会触发InstantiationAwareBeanPostProcessor中postProcessPropertyValues的调用
- initializeBean(beanName, exposedObject, mbd);// 1、触发BeanPostProcessor的postProcessBeforeInitialization 2、触发InitializingBean的afterPropertiesSet 3、触发BeanPostProcessor的postProcessAfterInitialization的调用
- 循环依赖解决
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// 把自己暴露在二级缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
// 从一级缓存中删除
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
// 走到这里,bean已经创建完成
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName); // 删除
this.earlySingletonObjects.remove(beanName); // 删除
this.registeredSingletons.add(beanName);
}
}
- 关键类的功能
- AutowiredAnnotationBeanPostProcessor:对@Autowired注解标记的对象进行注入
- DefaultSingletonBeanRegistry 注册bean,解决循环依赖
- 扩展点
- BeanPostProcessor
- InitializingBean
- InstantiationAwareBeanPostProcessor
12. finishRefresh
发布ContextRefreshedEvent事件
关于AOP
@EnableAspectJAutoProxy开启Aop,里面导入AspectJAutoProxyRegistrar类,这个类会注入一个AnnotationAwareAspectJAutoProxyCreator类,这个类是BeanPostProcesser接口的一个实现类,在initializeBean执行前后会执行接口总的实现方法,实现代理的效果。
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
下面放一个AOP的类关系图:
总结
- Spring先对beanFactory进行初始化工作
- 以启动类作为入口,扫描出所有可以读取到的class
- 对扫描出来的class进行解析,继续扫描出所有需要管理的class,全部封装为beanDefinition
- 找出所有的BeanPostProcessor并注册
- 遍历所有的beanName,实例化需要提前加载的bean。这里包括实例化、自动注入、初始化三个阶段。同时处理了循环依赖问题。每个阶段还包括对扩展点的调用。