1. Spring IoC 容器初始化主题流程
1.1 Spring IoC容器体系
- 容器是一组组件和过程的合集,包括BeanFactory、单例池、BeanPostProcessor等
用于存放和管理实例化对象的
**Map**集合其实是容器中的单例池BeanFactory
BeanFactory注释第一句话:
_The root interface for accessing a Spring bean container._
获取Bean对象
Object getBean- 获取Bean的提供者
<T> ObjectProvider<T> getBeanProvider - 判断Factory是否有Bean
boolean containsBean - 判断是否为单例Bean
boolean isSingleton - 判断是否为原型Bean
boolean isPrototype - 判断是否匹配类型
boolean isTypeMatch - 获取Bean类型
Class<?> getType - 获取别名
String[] getAliases - FactoryBean 定位符:
String _FACTORY_BEAN_PREFIX _= "&";- Spring的Bean分两种:普通Bean和FactoryBean,Spring会通过
"&"来定位区分FactoryBean1.2 Bean 生命周期关键时间点
| 关键点 | 触发代码 | | —- | —- | | 构造器执行、初始化方法调用 | refresh#finishBeanFactoryInitialization(beanFactory) | | BeanFactoryPostProcessor 初始化 | refresh#invokeBeanFactoryPostProcessors(beanFactory) | | BeanFactoryPostProcessor ⽅法调⽤ | refresh#invokeBeanFactoryPostProcessors(beanFactory) | | BeanPostProcessor 初始化 | refresh#registerBeanPostProcessors(beanFactory) | | BeanPostProcessor ⽅法调⽤ | refresh#finishBeanFactoryInitialization(beanFactory) |
- Spring的Bean分两种:普通Bean和FactoryBean,Spring会通过
SpringBean的生命周期
- Bean 容器找到配置文件中 Spring Bean 的定义。
- Bean 容器利用 Java Reflection API 创建一个 Bean 的实例。
- 如果涉及到一些属性值 利用
set()方法设置一些属性值。 - 如果 Bean 实现了 BeanNameAware 接口,调用
setBeanName()方法,传入 Bean 的名字。 - 如果 Bean 实现了 BeanClassLoaderAware 接口,调用
setBeanClassLoader()方法,传入 ClassLoader对象的实例。 - 如果 Bean 实现了 BeanFactoryAware 接口,调用
setBeanFactory()方法,传入 BeanFactory对象的实例。 - 与上面的类似,如果实现了其他 .*Aware接口,就调用相应的方法。
- 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行
postProcessBeforeInitialization()方法 - 如果 Bean 实现了InitializingBean接口,执行
afterPropertiesSet()方法。 - 如果 Bean 在配置文件中的定义包含
_ init-method_属性,执行指定的方法。 - 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行
postProcessAfterInitialization()方法 - 当要销毁 Bean 的时候,如果 Bean 实现了 DisposableBean 接口,执行
destroy()方法。 - 当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含
destroy-method属性,执行指定的方法。
1.3 容器初始化主流程
refersh() 方法
/*** Load or refresh the persistent representation of the configuration, which* might be from Java-based configuration, an XML file, a properties file, a* relational database schema, or some other format.* <p>As this is a startup method, it should destroy already created singletons* if it fails, to avoid dangling resources. In other words, after invocation* of this method, either all or no singletons at all should be instantiated.* @throws BeansException if the bean factory could not be initialized* @throws IllegalStateException if already initialized and multiple refresh* attempts are not supported*/@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing./** 刷新前的预处理* 设置spring容器的启动时间* 开启活跃状态,撤销关闭时间* 验证环境信息里一些必须属性*/prepareRefresh();// Tell the subclass to refresh the internal bean factory./** 获取BeanFactory; 默认实现是DefaultListableBeanFactory* 加载BeanDefinition并注册到BeanDefinitionRegistry*/ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context./** BeanFactory的准备工作,比如context的类加载器等*/prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.// 实例化实现了BeanFactoryPostProcessor接口的Bean,并调用接口方法/** 在此之前,所有bean definition都已加载,但还没有实例化任何bean。* BeanFactoryPostProcessor是针对BeanFactory的扩展,* 主要用在bean实例化之前,读取bean的定义,并可以修改它。*/invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.// 注册Bean的后置处理器// 本方法会注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类加载到 BeanFactory 中。registerBeanPostProcessors(beanFactory);// Initialize message source for this context.initMessageSource();// Initialize event multicaster for this context.initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.onRefresh();// Check for listener beans and register them.registerListeners();// Instantiate all remaining (non-lazy-init) singletons./** 初始化所有剩下的非懒加载的单例Bean* 创建非懒加载方式的单例Bean* 设置Bean的属性* 初始化方法调用* 调动BeanPostProcessor对实例Bean进行后置处理*/finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}}}
获取BeanFactory与加载BeanDefinitions
**ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();****obtainFreshBeanFactory()**:
/*** Tell the subclass to refresh the internal bean factory.* @return the fresh BeanFactory instance* @see #refreshBeanFactory()* @see #getBeanFactory()*/protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();return getBeanFactory();}
BeanDefinition
什么是BeanDefinition
- BeanDefinition描述一个bean实例,该实例具有属性值、构造函数参数值和由具体实现提供的进一步信息。
- BeanDefinition里存着bean的属性值,构造函数等等的信息。
- 其实就是将xml里的bean属性,存到了BeanDefinition的某些属性里面,用的时候,从BeanDefinition的这些属性里取值。
- 另外我们可以通过BeanFactoryPostProcessor来修改加载到BeanDefinition对象中的bean的属性。
BeanDefinition设置过程的调用链
Bean对象的创建流程

**beanFactory.preInstantiateSingletons();**
- 先处理FactoryBean
- 然后创建普通Bean,走
getBean()方法 doGetBean()方法- 做一些基础设置
- 以创建单例Bean为例:
Bean初始化的主体类

spring bean 的流程全在 AbstractAutowireCapableBeanFactory 类中实现
- 在第5步的
createBean,调用AbstractAutowireCapableBeanFactory实现的createBean方法

doCreateBean(beanName, mbdToUse, args);中的流程即是SpringBean的生命周期- 通过反射创建单例Bean:
instanceWrapper = createBeanInstance(beanName, mbd, args); - 设置Bean的属性:
populateBean(beanName, mbd, instanceWrapper); - 在
initializeBean(beanName, exposedObject, mbd);方法中:- 检查Aware借口并设置相关依赖
- 通过反射创建单例Bean:

2. **设置BeanPostProcessors 前置处理器**

3. **初始化方法**

4. **BeanPostProcessors 后置处理器**
延迟加载
循环依赖
无法解决
- 原型Bean的循环依赖无法解决
- 单例Bean构造器参数循环依赖无法解决
可以解决
- 单例Bean通过set方法或者
@Autowired注入依赖
循环依赖解决原理
假设Class A 和Class B 相互依赖
- 初始化A的过程中,先通过构造器生成A的实例,把他提前暴露到spring容器中(
singletonFactories三级缓存);(生命周期种的7.a)

- 给A设置属性
populateBean(beanName, mbd, instanceWrapper);(生命周期种的7.b) - 发现A依赖于B;
populateBean—>applyPropertyValues(beanName, mbd, bw, pvs)

AbstractBeanFactory 
- 开始创建B,设置属性之前 同创建A的流程一样;(这里就又回生命周期的2)
- 设置属性时发现依赖于A,同样和3的流程一样,直到走到AbstractBeanFactory的
doGetBean方法。
doGetBean方法中的getSingleton从缓存中获取A
- 首先从一级缓存(
singletonObjects)中获取,如果没有,然后二级缓存(earlySingletonObjects),然后三级缓存(singletonFactories),从三级缓存中拿到A的幼年期对象,然后加入了二级缓存;并从三级缓存中删除。

- 返回A的 幼年期(未创建完全)对象
- 创建B完成,加入一级缓存
- A从一级缓存中,获取B的依赖
2. Spring AOP
首先,springAOP是通过生成类的代理对象,进行方法增强,
所以,这时候正好就用到了beanPostProcesser


