一、前言

上次我们在手把手教你解决循环依赖,一步一步地来窥探出三级缓存的奥秘中分析了Spring解决循环依赖的方式,在第6节中的doCreateBean(AbstractAutowireCapablebeanFactory类中)其实已经隐约看到了Bean的生命周期的几个阶段。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { //实例化bean BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args); Boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { //加入到三级缓存中,getEarlyBeanReference会返回单例工厂 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } Object exposedObject = bean; //属性赋值 populateBean(beanName, mbd, instanceWrapper); //初始化 exposedObject = initializeBean(beanName, exposedObject, mbd); if (earlySingletonExposure) { //从二级缓存中查找 Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { //返回二级缓存中的bean,这里就有可能是代理后的对象 exposedObject = earlySingletonReference; } } //销毁前的准备,注册待销毁的Bean registerDisposableBeanIfNecessary(beanName, bean, mbd); return exposedobject; }

doCreateBean基本描述了Bean生命周期的大致框架——实例化、属性赋值与初始化,当然Bean最后一步就是销毁

基本阶段图

spring生命周期是什么(还记不住SpringBean的生命周期)(1)

请记住这张图,也许你等会儿就不认识它了。

二、实例化与属性赋值阶段

当容器启动时,会依据配置或注解扫描指定的包,将其中的类转化为BeanDefinition,并集中在DefaultListableBeanFactory类的beanDefinitionMap变量里。

Spring中的BeanDdfinition,可以用来描述一个bean的作用域、是否懒加载、是否单例等。

容器启动完成后,当我们试图从容器获取一个Bean时,第一步就是去实例化该Bean。说白了,就是需要调用构造方法。

注意到在调用doCreateBean之前,调用了resolveBeforeInstantiation方法。

1、resolveBeforeInstantiation

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { //省略部分代码 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } //正式进入生命周期 Object beanInstance = doCreateBean(beanName, mbdToUse, args); return beanInstance; } protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { //寻找InstantiationAwareBeanPostProcessor,并执行相应方法 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); //在返回不为null的情况下,寻找BeanPostProcessor,执行相应方法 if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }

当resolveBeforeInstantiation返回不为null的bean后,createBean会直接返回。也就是说,后续的实例化、属性赋值与初始化阶段都不会进行。这一步,将会给BeanPostProcessor一个返回代理而不是目前bean的机会。

resolveBeforeInstantiation核心的方法如下:

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { //获取所有BeanPostProcessor的实现类 for (BeanPostProcessor bp : getBeanPostProcessors()) { //如果属于InstantiationAwareBeanPostProcessor类型,则执行postProcessBeforeInstantiation方法 if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; } public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; //获取所有BeanPostProcessor的实现类 for (BeanPostProcessor processor : getBeanPostProcessors()) { //挨个执行postProcessAfterInitialization方法 Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }

2、BeanPostProcessor

BeanPostProcessor是容器提供给我们的一个扩展接口,也称Bean的后置处理器。我们可以实现该接口,用来添加业务中特有的逻辑。

BeanPostProcessor实现类也是一个普通的Bean,那么Spring是怎么保证BeanPostProcessor实现类在开发人员写的Bean之前加载的呢?

这就要回到我们最熟悉的refresh方法中

public void refresh() { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. 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. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); }

其中registerBeanPostProcessors方法就会对BeanPostProcessor进行注册,在finishBeanFactoryInitialization中再完成非懒加载的单例Bean的加载。

从而BeanPostProcessor就会在业务Bean之前加载,因此可以在业务Bean实例化前进行调用。

3、instantiateBean

现在可以进入doCreateBean中,createBeanInstance包含了实例化bean并封装为BeanWrapper的逻辑,且内部提供了多种实例化的方式。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { //将bean转化为class对象 Class<?> beanClass = resolveBeanClass(mbd, beanName); //基于Supplier实例化 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } //基于工厂方法实例化 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } //省略部分代码 //基于有参构造函数实例化 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } //基于无参构造函数实例化 return instantiateBean(beanName, mbd); }

有兴趣的同学,可以深入到这几种方式的内部,这里就不做探讨了。

4、populateBean

在实例化结束后,将进入属性赋值阶段。

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { //如果属于InstantiationAwareBeanPostProcessor类型,则调用postProcessAfterInstantiation if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } //一旦任意一个InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation返回false,属性注入阶段将不再进行,直接进入下一个阶段 if (!continueWithPropertyPopulation) { return; } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); //按照名称注入 if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } //按照类型注入 if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } //省略掉InstantiationAwareBeanPostProcessor其他两个扩展点及下面的依赖检查 if (pvs != null) { //属性注入 applyPropertyValues(beanName, mbd, bw, pvs); } }

到这里,实例化与属性赋值阶段结束,我们整理一下其中的扩展点

spring生命周期是什么(还记不住SpringBean的生命周期)(2)

三、初始化阶段

从doCreateBean内的initializeBean开始

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { //1.设置Aware相关依赖 if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } //2.调用BeanPostProcessor的前置处理 Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } //3.1调用InitializingBean的afterPropertiesSet方法 //3.2调用自定义的init method方法 try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } //4.调用BeanPostProcessor的后置处理 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }

1、设置Aware相关依赖

private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { //如果bean实现了BeanNameAware接口,则设置BeanName if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } //如果bean实现了BeanClassLoaderAware接口,则设置BeanClassLoader if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } //如果bean实现了BeanFactoryAware接口,则设置BeanFactory if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }

从这里可以看出,只要Bean实现了指定的Aware接口,Spring就会向Bean注入这些Aware相关信息。

2、调用BeanPostProcessor的前置处理

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; //获取所有BeanPostProcessor的实现类 for (BeanPostProcessor processor : getBeanPostProcessors()) { //挨个调用postProcessBeforeInitialization方法 Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }

这一步会获取容器中所有BeanPostProcessor的实现类,挨个调用postProcessBeforeInitialization方法。在其返回不为null的情况下,后一个结果会覆盖上一个结果。

当然在处理到ApplicationContextAwareProcessor的时候,会设置以下Aware依赖。

在处理到InitDestroyAnnotationBeanPostProcessor,会找出被@PostConstruct注解修饰的方法,并执行。

3、invokeInitMethods

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { //如果实现了InitializingBean接口,则调用afterPropertiesSet方法 boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isTraceEnabled()) { logger.trace("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) bean).afterPropertiesSet(); } } //调用xml中声明的init-method指定的方法 if (mbd != null && bean.getClass() != NullBean.class) { String initMethodName = mbd.getInitMethodName(); if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { invokeCustomInitMethod(beanName, bean, mbd); } } }

4、调用BeanPostProcessor的后置处理

和前置处理类似,只是调用postProcessAfterInitialization方法,不再赘述。

因此,初始化过程又可以被细分为

spring生命周期是什么(还记不住SpringBean的生命周期)(3)

四、销毁阶段

在容器关闭的时候,会进入Bean的销毁阶段,代码从AbstractApplicationContext的close()方法开始

不急着进入close()方法,先看一下第一节代码中最末尾的方法:

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); //如果Bean不是多例且需要在容器关闭时销毁 if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { //给当前Bean绑定一个DisposableBeanAdapter registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } else { // A bean with a custom scope... Scope scope = this.scopes.get(mbd.getScope()); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" mbd.getScope() "'"); } scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } } } public void registerDisposableBean(String beanName, DisposableBean bean) { synchronized (this.disposableBeans) { this.disposableBeans.put(beanName, bean); } }

在registerDisposableBeanIfNecessary中,会对每一个需要在容器关闭时进行销毁的单例Bean,绑定对应的DisposableBeanAdapter对象。最后把这些Bean及其DisposableBeanAdapter放入进名称为disposableBeans的map中,以供后续使用。

现在我们进入AbstractApplicationContext的close()方法

一路上兜兜转转,会进入到DefaultSingletonBeanRegistry的destroySingletons方法中

public void destroySingletons() { String[] disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet()); for (int i = disposableBeanNames.length - 1; i >= 0; i--) { destroySingleton(disposableBeanNames[i]); } //省略部分代码 }

先拿到所有待销毁Bean的名称,挨个调用destroySingleton方法,一直往下走,最终会进入到DefaultSingletonBeanRegistry的destroyBean中

其中核心的一句

// Actually destroy the bean now... bean.destroy();

按照beanName从disposableBeans中获取到bean对应的DisposableBeanAdapter,调用其destroy方法

public void destroy() { //调用被@PreDestroy注解修饰的方法 //具体可以跟进InitDestroyAnnotationBeanPostProcessor类 if (!CollectionUtils.isEmpty(this.beanPostProcessors)) { for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) { processor.postProcessBeforeDestruction(this.bean, this.beanName); } } //如果实现了DisposableBean接口,则调用destroy方法 if (this.invokeDisposableBean) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((DisposableBean) this.bean).destroy(); return null; }, this.acc); } else { ((DisposableBean) this.bean).destroy(); } } //调用xml中自定义的destroy-method方法 if (this.destroyMethod != null) { invokeCustomDestroyMethod(this.destroyMethod); } else if (this.destroyMethodName != null) { Method methodToCall = determineDestroyMethod(this.destroyMethodName); if (methodToCall != null) { invokeCustomDestroyMethod(methodToCall); } } }

到这里,Bean的销毁过程基本就结束了,我们使用一张图来概括下:

spring生命周期是什么(还记不住SpringBean的生命周期)(4)

五、生命周期的全流程

我们整个阶段串联起来

spring生命周期是什么(还记不住SpringBean的生命周期)(5)

六、代码验证

待观察的Bean

public class A implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean { private int id; public int getId() { return id; } public void setId(int id) { this.id = id; System.out.println("属性赋值"); } private A() { System.out.println("实例化"); } @PostConstruct public void postConstruct() { System.out.println("@PostConstruct指定的方法"); } @Override public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("BeanClassLoaderAware.setBeanClassLoader"); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("BeanFactoryAware.setBeanFactory"); } @Override public void setBeanName(String name) { System.out.println("BeanNameAware.setBeanName"); } @Override public void afterPropertiesSet() { System.out.println("InitializingBean.afterPropertiesSet"); } public void initMethod() { System.out.println("xml中init-method指定的方法"); } @PreDestroy public void preDestroy() { System.out.println("@PreDestroy指定的方法"); } @Override public void destroy() { System.out.println("DisposableBean.destroy"); } public void destroyMethod() { System.out.println("xml中destroy-method指定的方法"); } }

自定义的BeanPostProcessor

public class BeanPostProcessorImpl implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("a")) { System.out.println("BeanPostProcessor.postProcessBeforeInitialization"); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("a")) { System.out.println("BeanPostProcessor.postProcessAfterInitialization"); } return bean; } }

自定义的InstantiationAwareBeanPostProcessorImpl

public class InstantiationAwareBeanPostProcessorImpl implements InstantiationAwareBeanPostProcessor { @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if (beanName.equals("a")) { System.out.println("InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation"); } return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if (beanName.equals("a")) { System.out.println("InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation"); } //如果这里返回false,那么所有Bean将不进行属性赋值 return true; } }

spring.xml配置

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.yang.ym"/> <bean id="a" class="com.yang.ym.testBean.A" init-method="initMethod" destroy-method="destroyMethod"> <property name="id" value="1"/> </bean> <bean class="com.yang.ym.testBean.BeanPostProcessorImpl"/> <bean class="com.yang.ym.testBean.InstantiationAwareBeanPostProcessorImpl"/> </beans>

测试类

@Test public void get() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); A a = (A) context.getBean("a"); System.out.println("关闭容器"); context.close(); }

输出结果:

InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation 实例化 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation 属性赋值 BeanNameAware.setBeanName BeanClassLoaderAware.setBeanClassLoader BeanFactoryAware.setBeanFactory BeanPostProcessor.postProcessBeforeInitialization @PostConstruct指定的方法 InitializingBean.afterPropertiesSet xml中init-method指定的方法 BeanPostProcessor.postProcessAfterInitialization 关闭容器 @PreDestroy指定的方法 DisposableBean.destroy xml中destroy-method指定的方法

七、总结

先记住4个大阶段,实例化、属性赋值、初始化与销毁。

在生命周期内部,可以自定义Bean后置处理器以及实现接口的形式来进行扩展

此外,可以使用注解或xml配置形式,指定扩展点

那么再记忆生命周期的先后顺序,就会容易很多:

getBean

关闭容器后

  1. @PreDestroy指定的方法
  2. DisposableBean.destroy
  3. xml中destroy-method指定的方法
,