Bean的生命周期可分为四大步骤
- Bean实例化
- Bean属性赋值
- Bean初始化
- 销毁
在传统的Java应用中,bean的生命周期很简单,使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了。一旦bean不再被使用,则由Java自动进行垃圾回收。Spring管理Bean的生命周期就复杂多了,Bean 的生命周期是还是Spring面试的一道热点问题。
下面是根据源码画的一个大致的Bean生命周期流程图,Bean生命周期主要逻辑在AbstractAutowireCapableBeanFactory类的doCreateBean()方法中,Bean实例化,属性赋值,初始化三个顺序执行
Bean实例化的时候会根据条件,选择合适的实例化方式进行实例化,,如工厂方法,带参构造实例化,无参构造实例化,
// 部分源码
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
if (instanceWrapper == null) {
//创建bean实例化 使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化。。
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
}
进入创建Bean实例的方法,调用需要的实例化策略
// createBeanInstance中的部分源码
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//从bean定义中解析出当前bean的class对象
Class<?> beanClass = resolveBeanClass(mbd, beanName);
/**
* 该方法是spring5.0 新增加的 如果存在 Supplier 回调,则使用给定的回调方法初始化策略
*/
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
/**
* 工厂方法,我们通过配置类来进行配置的话 采用的就是工厂方法,方法名称就是tulingDao就是我们工厂方法的名称
* @Bean会在这创建实例
*/
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
//若被解析过
if (resolved) {
if (autowireNecessary) {
//通过有参的构造函数进行反射调用
return autowireConstructor(beanName, mbd, null, null);
}
else {
//调用无参数的构造函数进行创建对象
return instantiateBean(beanName, mbd);
}
}
/**
* 通过bean的后置处理器进行选举出合适的构造函数对象
*/
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
/**
* 如果自定义了BeanPostProcessor返回了构造器 或者
* 使用构造器自动装配模式 或者
* 设置了BeanDefinition构造器参数 或者
* 有参数:即getBean(String name, Object... args) 中的args
* 则使用自定义的构造器初始化
*/
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//通过构造函数创建对象
return autowireConstructor(beanName, mbd, ctors, args);
}
//使用无参数的构造函数调用创建对象
return instantiateBean(beanName, mbd);
}
Bean实例化后进行属性赋值,调用populateBean(beanName, mbd, instanceWrapper);方法进行属性赋值,根据不同的方式进行属性注入
// 部分源码
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
/**
* 判断我们的bean的属性注入模型
* AUTOWIRE_BY_NAME 根据名称注入
* AUTOWIRE_BY_TYPE 根据类型注入
*/
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
//把PropertyValues封装成为MutablePropertyValues
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//根据bean的属性名称注入
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
//根据bean的类型进行注入
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
//把处理过的 属性覆盖原来的
pvs = newPvs;
}
}
属性注入后调用initializeBean(beanName, exposedObject, mbd);方法进行Bean的初始化。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//若我们的bean实现了XXXAware接口进行方法的回调
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//调用我们的bean的后置处理器的postProcessorsBeforeInitialization方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//调用初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//调用我们bean的后置处理器的PostProcessorsAfterInitialization方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
看源码可以发现,在调用真正的初始化方法之前会先调用invokeAwareMethods(beanName, bean);来检测是否实现了XXXAware接口
步骤:调用BeanNameAware接口的setBeanName方法》调用BeanClassLoaderAware的setBeanClassLoader方法》调用BeanFactoryAware的setBeanFactory方法,源码如下
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
//我们的bean实现了BeanNameAware
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
//实现了BeanClassLoaderAware接口
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
//实现了BeanFactoryAware
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
调用自己的初始化方法
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
//判断我们的容器中是否实现了InitializingBean接口
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//回调InitializingBean的afterPropertiesSet()方法
((InitializingBean) bean).afterPropertiesSet();
}
}
// 调用initMethod
if (mbd != null && bean.getClass() != NullBean.class) {
//我们beanclass中看是否有自己定义的init方法
String initMethodName = mbd.getInitMethodName();
//判断自定义的init方法名称不叫afterPropertiesSet
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
//调用我们自己的初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
Bean实例化之后会去调用调我们bean的后置处理器的PostProcessorsAfterInitialization方法,在执行这个方法的时候会为需要代理的类创建代理对象,也就是AOP代理
if (mbd == null || !mbd.isSynthetic()) {
//调用我们bean的后置处理器的PostProcessorsAfterInitialization方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//获取我们容器中的所有的bean的后置处理器
for (BeanPostProcessor processor : getBeanPostProcessors()) {
/**
*
* 在这里实现的是BeanPostProcessor接口的postProcessAfterInitialization来生成我们的代理对象
*/
Object current = processor.postProcessAfterInitialization(result, beanName);
//若只有有一个返回null 那么直接返回原始的
if (current == null) {
return result;
}
result = current;
}
return result;
}
Bean初始化完成之后就可以使用啦。
总结
- Spring启动的时候查找需要被Spring管理的Bean进行实例化
- 实例化后对Bean进行属性注入
- 如果Bean实现了BeanNameAware接口,Spring将Bean的Id传递给setBeanName()方法
- 如果Bean实现了BeanClassLoaderAware接口的话,Spring将调用setBeanClassLoader()方法
- 如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入
- 如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法
- 如果Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法
- 如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法
- 如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用