Bean的生命周期可以理解为以下几个步骤:
一、bean的定义
bean的定义一般是由我们开发者来完成的,第一种方法是在spring主配置文件中定义一个bean
<bean id="stu" class="com.apesource.jopo.student">
<property name="sname" value="鲁智深"/>
<property name="sage" value=17/>
</bean>
第二种是用注解直接注入
@Component
public class Stu{
private String sname;
private int sage;
}
第三种是在配置类中使用@Bean
二、bean的实例化
Bean已经定义好了,在spring启动时就会将定义好的Bean进行注册,然后调用了refresh()方法
//源码
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
//用来解析配置文件,知道那些Bean需要被创建
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
//实例化单例Bean的方法
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
finishBeanFactoryInitialization()是实例化单例Bean的方法(通过反射的方式):源代码如下
//单例Bean实例化方法finishBeanFactoryInitialization()
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}
beanFactory.setTempClassLoader((ClassLoader)null);
beanFactory.freezeConfiguration();
//此方法实例化了所有的单例Bean
beanFactory.preInstantiateSingletons();
}
三、bean的属性赋值
在对象的创建过程中,需要给对象进行属性赋值,这里调用了Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)中的this.populateBean(beanName, mbd, instanceWrapper)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
// 获取Bean实例,这里的普通实例是相对AOP代理的Bean而言的。普通bean大部分都是通过反射利用构造方法创建对象
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 创建Bean的ObjectFactory的对象,并且把他加到第三级缓存中,主要用来解决循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// 给普通实例Bean填充属性,比如Bean里面有属性带了@Autowired,就是给里面的属性赋值
Object exposedObject = bean;
populateBean(beanName, mbd, instanceWrapper);
//执行Bean的初始化的前置回调方法、初始化回调方法、初始化的后置回调方法(回调了部分的Aware接口),(AOP代理的Bean大部分都是通过后置回调方法创建的)
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
// 从一级或者二级缓存中获取Bean的实例,不从三级缓存中取
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
}
}
return exposedObject;
}
postProcessProperties方法会完成属性注入:这个方法有2个比较重要的实现类
AutowiredAnnotationBeanPostProcessor在这个方法中对@Autowired、@Value标注的字段、方法注入值。@Autowired注解在上一篇有专门讲解
CommonAnnotationBeanPostProcessor在这个方法中对@Resource标注的字段和方法注入值。
完成注入属性,调用的是部分的Aware接口,spring中配置了很多,在不同的时机调用
四、Bean的初始化
初始化阶段分为两个过程:
1.如果bean实现了InitializingBean接口,则执行其 afterPropertiesSet()方法,进行bean的初始化
2.调用bean定义的时候指定的初始化方法init()
指定bean的初始化方法的方式
方式1:xml方式指定初始化方法 <bean init- method="bean中方法名称"/>
方式2:@Bean的方式指定初始化方法@Bean(initMethod ="初始化的方法")
五、Bean的销毁
当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法。