共计 6481 个字符,预计需要花费 17 分钟才能阅读完成。
概述
生命周期大抵分为四步, 当然源代码的作者没有分这么分明,次要是为了了解不便,创立 bean 的次要流程代码在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance.doCreateBean
中
- 实例化筹备
- 实例化
- 属性注入
- 初始化
实例化筹备
对于一般 java 对象来说,创建对象只需四步
- 编译 Java 文件,生成.class 文件
- 收到 new 或者反射创立一个对象的信号
- 将 class 文件通过类加载器加载进 JVM 虚拟机
- 初始化对象可供使用
而 Bean 对象不同,Bean 能够通过 xml 定义,能够通过注解(@Component
,@Configuration
等)定义。
SpringBoot 启动时,依据 @ComponentScan
的范畴扫描,并把定义封装进 BeanDefinition 实例,其中有定义的很多元数据,如 @Scope
,@Lazy
等等,最初把收集的 BeanDefinition 放入 beanDefinitionMap 中,key 是 beanName,value 是 BeanDefinition 对象。
万恶之源:org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
1. 通过 bean 名字获取 BeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
2. 调用 BeanPostProcessors 对 bean 的元信息进行解决(个别不必
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {return bean;}
}
3. 调用 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
创立 bean
try {Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean'" + beanName + "'");
}
return beanInstance;
}
从而进入 doCreateBean
进行实例化
实例化
1.SpringBoot 先查问缓存,如果缓存中没有再实例化 bean。
实例化的代码如下#createBeanInstance
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}
2. 实例实现后,BeanPostProcessor 进行后处理,这是为了查找出满足条件的属性、办法, 将他们封装起来, 以便前面在填充属性的时候能够间接应用。#applyMergedBeanDefinitionPostProcessors
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {
try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
3. 将这个 bean 退出到三级缓存中。#addSingletonFactory
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean'" + beanName +
"'to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
属性注入
代码如下#populateBean
// Initialize the bean instance.
Object exposedObject = bean;
try {populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
留神到属性注入后,有这么一段代码
if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name'" + beanName + "'has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been" +
"wrapped. This means that said other beans do not use the final version of the" +
"bean. This is often the result of over-eager type matching - consider using" +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
这段代码是判断缓存中的 bean 和本人创立的 bean 的地址是否雷同,如果不同,就会接着判断!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)
, 如果为 true,就会抛异样。
初始化
在初始化过程,能够设置很多的 Hook。
Aware 接口
Aware 接口也叫感知接口,实现这个接口的类能够
- BeanNameAware 取得到容器中 Bean 的名称
- BeanFactoryAware 取得以后 bean Factory, 从而调用容器的服务
- ApplicationContextAware 取得以后的 application context 从而调用容器的服务
- MessageSourceAware 失去 message source 从而失去文本信息
- ApplicationEventPublisherAware 利用工夫公布器, 用于公布事件
- ResourceLoaderAware 获取资源加载器, 能够取得内部资源文件
BeanPostProcessor
用法:实现 BeanPostProcessor 接口并重写办法
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException{System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
return bean;
}
}
源码解析
其余
其余的接口差不多都很简略了,请自行 review。
要害源码办法(强烈建议本人去撸一遍)
org.springframework.context.support.AbstractApplicationContext#refresh
(入口)org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
(初始化单例对象入口)org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons
(初始化单例对象入口)org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
(万恶之源,获取并创立 Bean 的入口)org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
(理论的获取并创立 Bean 的实现)org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)
(从缓存中尝试获取)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
(实例化 Bean)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
(实例化 Bean 具体实现)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
(具体实例化过程)org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory
(将实例化后的 Bean 增加到三级缓存)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
(实例化后属性注入)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
(初始化入口)
参考文章
- 怎么了解 spring bean 的生命周期,理论利用场景?
- Spring 源码剖析 - 八、applyMergedBeanDefinitionPostProcessors 源码剖析