上面两篇文章分别介绍了spring生命周期中初始化和销毁的几种方式以及统一后置BeanPostProcessor接口的使用,可以点击以下链接查看:


  1. 三分钟了解spring-bean生命周期之初始化和销毁的三种方式

  2. 一分钟学会spring-bean的统一前后置处理器BeanPostProcessor


今天我们就来一起看看spring底层是如何实现这些的,在看它的实现原理之前,我们再来把之前几种方式结合放一个例子中演示下


新建一个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();
}


运行结果如下:


实例化User1的构造方法......
postProcessBeforeInitialization====getUser1
调用实现InitializingBean的afterPropertiesSet方法......
执行initMethod方法.....
postProcessAfterInitialization====getUser1
调用实现DisposableBean的destroy方法....
执行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中


到此今天所有内容就到此结束了,最后以一张流程图总结下如下:


以上是今天文章的所有内容,欢迎大家吐槽


推荐阅读


深入理解java注解的实现原理 深入理解java的反射机制

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1250G偷懒必看资料全集


更多优质文章请关注以下公众号查阅:


640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1