深入理解spring生命周期与BeanPostProcessor的实现原理

本文深入解析Spring框架中Bean的生命周期,包括Bean的实例化过程、初始化阶段、销毁流程及BeanPostProcessor的作用时机。通过具体代码示例,阐述了InitializingBean、DisposableBean接口的实现与调用顺序,以及@Bean注解的initMethod和destroyMethod属性如何影响Bean的生命周期。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://blog.youkuaiyun.com/varyall/article/details/82257202
https://segmentfault.com/a/1190000015830477#%E5%A4%9A%E4%B8%AAbeanpostprocessor%E5%85%88%E6%B3%A8%E5%86%8C%E7%9A%84%E4%BC%9A%E4%B8%8D%E4%BC%9A%E5%AF%B9%E5%90%8E%E9%9D%A2%E6%B3%A8%E5%86%8C%E7%9A%84beanpostprocessor%E8%B5%B7%E4%BD%9C%E7%94%A8

新建一个User1对象如下:

/**

* 定义一个实现InitializingBean DisposableBean的bean

*

* @author zhangqh

* @date 2018年5月4日

*/

public class User1 implements InitializingBean,DisposableBean{

   public User1(){

       System.out.println("实例化User1的构造方法......");

   }

   public void destroy() throws Exception {

       System.out.println("调用实现DisposableBean的destroy方法....");

   }

   public void afterPropertiesSet() throws Exception {

       System.out.println("调用实现InitializingBean的afterPropertiesSet方法......");

   }

   public void initUser(){

       System.out.println("执行initMethod方法.....");

   }

   public void destroyUser(){

       System.out.println("执行destroyMethod方法......");

   }

}

 

新建一个MyBeanPostProcessor实现BeanPostProcessor如下:

/**

* 定义一个前置后置处理器

*

* @author zhangqh

* @date 2018年5月6日

*/

public class MyBeanPostProcessor implements BeanPostProcessor {

   public Object postProcessBeforeInitialization(Object bean, String beanName)

           throws BeansException {

       // 这边只做简单打印   原样返回bean

       System.out.println("postProcessBeforeInitialization===="+beanName);

       return bean;

   }

   public Object postProcessAfterInitialization(Object bean, String beanName)

           throws BeansException {

       // 这边只做简单打印   原样返回bean

       System.out.println("postProcessAfterInitialization===="+beanName);

       return bean;

   }

}
 ​​​

主配置文件如下:

 

 
/**

* 定义一个注解配置文件 必须要加上@Configuration注解

*

* @author zhangqh

* @date 2018年4月30日

*/

@Configuration

public class MainConfig {

   @Bean(initMethod="initUser",destroyMethod="destroyUser")

   public User1 getUser1(){

       return new User1();

   }

   @Bean

   public MyBeanPostProcessor getMyBeanPostProcessor(){

       return new MyBeanPostProcessor();

   }

}

 

测试代码如下:

 

 
public static void main(String[] args) {

       // 使用AnnotationConfigApplicationContext获取spring容器ApplicationContext2

       AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainConfig.class);

       applicationContext2.close();

}

运行结果如下:

 

  1. 实例化User1的构造方法......

  2. postProcessBeforeInitialization====getUser1

  3. 调用实现InitializingBean的afterPropertiesSet方法......

  4. 执行initMethod方法.....

  5. postProcessAfterInitialization====getUser1

  6. 调用实现DisposableBean的destroy方法....

  7. 执行destroyMethod方法......

 

从结果中可以看出他们之前执行的顺序如下:注意其中的位置序号下边文章会用到

1,首先执行bean的构造方法,
2,BeanPostProcessor的postProcessBeforeInitialization方法
3,InitializingBean的afterPropertiesSet方法
4,@Bean注解的initMethod方法
5,BeanPostProcessor的postProcessAfterInitialization方法
6,DisposableBean的destroy方法
7,@Bean注解的destroyMethod方法

接下来我们再来看看spring底层的实现,首先进入程序的启动类AnnotationConfigApplicationContext方法如下:

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {

       this();

       register(annotatedClasses);

       refresh();

}

里边有两个方法一个是register注册对应的java配置类和另一个是refresh方法,我们重点来看这个refresh方法如下:

 ​​​​​​​
public void refresh() throws BeansException, IllegalStateException {

       synchronized (this.startupShutdownMonitor) {

           // 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);

           try {

               // 省略大部分代码

               // 实例化所有的不是延迟加载(延迟加载的只有在使用的时候才会实例化)的bean实例

               finishBeanFactoryInitialization(beanFactory);

               // Last step: publish corresponding event.

               finishRefresh();

           }catch (BeansException ex) {

               // 省略部分代码

           }finally {

               resetCommonCaches();

           }

       }

}

接下来我们重点来看下finishBeanFactoryInitialization实例化bean的方法,进去之后我们发现最后有一个preInstantiateSingletons方法如下:

 

 ​​​​​
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

       // 省略大部分代码

       // Instantiate all remaining (non-lazy-init) singletons.

       beanFactory.preInstantiateSingletons();

}

继续查看preInstantiateSingletons对应实现如下:

 

 
@Override

   public void preInstantiateSingletons() throws BeansException {

       // Iterate over a copy to allow for init methods which in turn register new bean definitions.

       // While this may not be part of the regular factory bootstrap, it does otherwise work fine.

       List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

       // 循环所有的bean实例化

       for (String beanName : beanNames) {

           RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

           if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {

               if (isFactoryBean(beanName)) {

                   final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);

                   boolean isEagerInit;

                   if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {

                       isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {

                           @Override

                           public Boolean run() {

                               return ((SmartFactoryBean<?>) factory).isEagerInit();

                           }

                       }, getAccessControlContext());

                   }

                   else {

                       isEagerInit = (factory instanceof SmartFactoryBean &&

                               ((SmartFactoryBean<?>) factory).isEagerInit());

                   }

                   if (isEagerInit) {

                       // 获取bean方法

                       getBean(beanName);

                   }

               }

               else {

                   getBean(beanName);

               }

           }

       }

       // 省略部分代码

}

我们发现里边的关键方法getBean如下:

 
@Override

public Object getBean(String name) throws BeansException {

       return doGetBean(name, null, null, false);

}

继续跟进去如下:

 

 
protected <T> T doGetBean(

           final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)

           throws BeansException {

       final String beanName = transformedBeanName(name);

       Object bean;

       // 检查缓存中是否已经存在了bean实例.

       Object sharedInstance = getSingleton(beanName);

       if (sharedInstance != null && args == null) {

           if (logger.isDebugEnabled()) {

               if (isSingletonCurrentlyInCreation(beanName)) {

                   logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +

                           "' that is not fully initialized yet - a consequence of a circular reference");

               }

               else {

                   logger.debug("Returning cached instance of singleton bean '" + beanName + "'");

               }

           }

           bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

       }else {

           // 省略部分代码。。。。。

           try {

               // 省略部分代码。。。。。

               // 判断bean是否配置的是单实例

               if (mbd.isSingleton()) {

                   sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {

                       @Override

                       public Object getObject() throws BeansException {

                           try {

                               return createBean(beanName, mbd, args);

                           }

                           catch (BeansException ex) {

                               destroySingleton(beanName);

                               throw ex;

                           }

                       }

                   });

                   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

               }// bean配置的是多实例

               else if (mbd.isPrototype()) {

                   // It's a prototype -> create a new instance.

                   Object prototypeInstance = null;

                   try {

                       beforePrototypeCreation(beanName);

                       prototypeInstance = createBean(beanName, mbd, args);

                   }

                   finally {

                       afterPrototypeCreation(beanName);

                   }

                   bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);

               }

               else {// 既不是单实例也不是多实例的逻辑

                   // 省略部分代码。。。。。

               }

           }

           catch (BeansException ex) {

               cleanupAfterBeanCreationFailure(beanName);

               throw ex;

           }

       }

       // 省略部分代码。。。。。

       return (T) bean;

   }

接下来重点看一下其中创建bean的方法createBean如下:

 

 
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {

       RootBeanDefinition mbdToUse = mbd;

       // 省略部分代码

       // 重点注意doCreateBean方法

       Object beanInstance = doCreateBean(beanName, mbdToUse, args);

       if (logger.isDebugEnabled()) {

           logger.debug("Finished creating instance of bean '" + beanName + "'");

       }

       return beanInstance;

}

继续跟进可以看到doCreateBean方法如下:

 

 ​​​​​​​
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)

           throws BeanCreationException {

       // 省略部分代码

       // Initialize the bean instance.

       Object exposedObject = bean;

       try {

           populateBean(beanName, mbd, instanceWrapper);

           if (exposedObject != null) {

               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);

           }

       }

       // 省略部分代码......

       // Register bean as disposable.

       // 注意这个地方  下面讲销毁的时候说讲到

       try {

           registerDisposableBeanIfNecessary(beanName, bean, mbd);

       }

       catch (BeanDefinitionValidationException ex) {

           throw new BeanCreationException(

                   mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);

       }

       return exposedObject;

}

可以发现其中有一个initializeBean方法如下:

 

 
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {

       // 省略部分代码。。。。

       Object wrappedBean = bean;

       if (mbd == null || !mbd.isSynthetic()) {

           // 重点来了BeanPostProcessor的postProcessBeforeInitialization方法执行的地方

           // 这也是为什么他执行所有的初始化之前的原因了

           wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

       }

       try {

           // 初始化bean

           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()) {

           // BeanPostProcessor的PostProcessorsAfterInitialization方法执行的地方

           // 初始化完成之后执行BeanPostProcessor的postProcessorsAfterInitialization

           wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

       }

       return wrappedBean;

}

到这BeanPostProcessor的实现已经很清晰了吧BeanPostProcessorpostProcessBeforeInitialization(方法位置2)BeanPostProcessorpostProcessAfterInitialization(方法位置5)的执行位置我们搞清楚了,那上面的位置3位置4又是怎么执行的呢,让我们继续到invokeInitMethods里边看看如下:

 

 

 ​​​​​​​
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)

           throws Throwable {

       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(new PrivilegedExceptionAction<Object>() {

                       @Override

                       public Object run() throws Exception {

                           ((InitializingBean) bean).afterPropertiesSet();

                           return null;

                       }

                   }, getAccessControlContext());

               }

               catch (PrivilegedActionException pae) {

                   throw pae.getException();

               }

           }

           else {

               // 位置3的 InitializingBean的afterPropertiesSet方法

               ((InitializingBean) bean).afterPropertiesSet();

           }

       }

       if (mbd != null) {

           // 位置4的 @Bean注解的initMethod方法

           String initMethodName = mbd.getInitMethodName();

           if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&

                   !mbd.isExternallyManagedInitMethod(initMethodName)) {

               invokeCustomInitMethod(beanName, bean, mbd);

           }

       }

}

聪明的你应该一眼就能看到位置3,以及位置4的执行顺序了吧

 

好了初始化的逻辑部分搞清楚了,接下来我们一起来看看销毁的流程,销毁开始于applicationContext.close();方法,点进去看如下:

 

 
@Override

public void close() {

       synchronized (this.startupShutdownMonitor) {

           doClose();

           // If we registered a JVM shutdown hook, we don't need it anymore now:

           // We've already explicitly closed the context.

           if (this.shutdownHook != null) {

               try {

                   Runtime.getRuntime().removeShutdownHook(this.shutdownHook);

               }

               catch (IllegalStateException ex) {

                   // ignore - VM is already shutting down

               }

           }

       }

}

看到其中有一个doClose继续跟进去看会发现有一个destroyBeans方法,再进去直到找到destroySingletons方法如下:

 

 
public void destroySingletons() {

       // 省略部分代码

       // 循环所有的disposableBean执行对应的destroy方法

       for (int i = disposableBeanNames.length - 1; i >= 0; i--) {

           destroySingleton(disposableBeanNames[i]);

       }

       // 省略部分代码

}

在继续从destroySingleton方法进去可以找到destroyBean方法如下:

 

 ​​​​​​​
protected void destroyBean(String beanName, DisposableBean bean) {

       // 省略部分代码

       // 重点的地方到了  执行DisposableBean 中的destroy 也就是位置6 中对应的打印

       if (bean != null) {

           try {

               bean.destroy();

           }

           catch (Throwable ex) {

               logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);

           }

       }

       // 省略部分代码

}

到这里我们已经完成了90%的原理分析了,这个时候细心的你一定会发现那位置7中的@Bean注解中配置的destroyMethod是在什么时候调用的呢,好像上面都没有讲到,要想知道destroyMethod的调用让我们回到上面讲bean初始化中的doCreateBean方法中其中有一个registerDisposableBeanIfNecessary方法进去看如下:

 

 

 ​​​​​​​
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {

       AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);

       if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {

           if (mbd.isSingleton()) {

               // Register a DisposableBean implementation that performs all destruction

               // work for the given bean: DestructionAwareBeanPostProcessors,

               // DisposableBean interface, custom destroy method.

               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));

           }

       }

}

继续进去到DisposableBeanAdapter类如下:

 

 ​​​​​​​
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,

           List<BeanPostProcessor> postProcessors, AccessControlContext acc) {

       Assert.notNull(bean, "Disposable bean must not be null");

       this.bean = bean;

       this.beanName = beanName;

       this.invokeDisposableBean =

               (this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));

       this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();

       this.acc = acc;

       String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);

       if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&

               !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {

           this.destroyMethodName = destroyMethodName;

           this.destroyMethod = determineDestroyMethod();

           if (this.destroyMethod == null) {

               if (beanDefinition.isEnforceDestroyMethod()) {

                   throw new BeanDefinitionValidationException("Couldn't find a destroy method named '" +

                           destroyMethodName + "' on bean with name '" + beanName + "'");

               }

           }

           else {

               Class<?>[] paramTypes = this.destroyMethod.getParameterTypes();

               if (paramTypes.length > 1) {

                   throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +

                           beanName + "' has more than one parameter - not supported as destroy method");

               }

               else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {

                   throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +

                           beanName + "' has a non-boolean parameter - not supported as destroy method");

               }

           }

       }

       this.beanPostProcessors = filterPostProcessors(postProcessors, bean);

   }

怎么样,到现在是不是就很清晰了,位置7的打印其实也是DisposableBean方法中打印出来的,@bean注解的destroyMethod其实是在初始化的时候转换成DisposableBean的实现放入到了disposableBeans中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值