概述
生命周期大致分为四步,当然源代码的作者没有分这么清楚,主要是为了理解方便,创建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 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)
(初始化入口)