spring (二)源码分析bean的生命周期

各位如果饱读诗书,应该对下图不陌生,然鹅有图无真相,这篇文章咱们来扣一下源码
在这里插入图片描述

1.Spring对bean进行实例化;
2.Spring将值和bean的引用注入到bean对应的属性中;
3.如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBean-Name()方法;
4.如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将 BeanFactory容器实例传入;
5.如果bean实现了ApplicationContextAware接口,Spring将调 用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来;
6.如果bean实现了BeanPostProcessor接口,Spring将调用它们的post- ProcessBeforeInitialization()方法;
7.如果bean实现了InitializingBean接口,Spring将调用它们的after- PropertiesSet()方法。类似地,如果bean使用init-method声明了初始化方法,该方法也 会被调用;
8.如果bean实现了BeanPostProcessor接口,Spring将调用它们的post- ProcessAfterInitialization()方法;
9.此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该 应用上下文被销毁;
10.如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样, 如果bean使用destroy-method声明了销毁方法,该方法也会被调用。

这么长的小作文真心不想背,那我们来调试一下看看

public void test01(){
   //创建ioc容器
   AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
   System.out.println("容器创建完成...");
   applicationContext.close();
}

没错,有价值的代码就是new AnnotationConfigApplicationContext
看那一下具体实现,无参构造>注册配置类>刷新

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
   this();
   register(annotatedClasses);
   refresh();
}

接下来我们点进去refresh方法

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

主要业务逻辑里面我们应该关注的是finishBeanFactoryInitialization---------实例化剩余的bean

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

根据断点我们直接关注AbstractAutowireCapableBeanFactory这里类的doCreateBean方法,该方法会首先实例化bean

if (mbd.isSingleton()) {
   instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
   instanceWrapper = createBeanInstance(beanName, mbd, args);
}

然后对bean进行属性赋值

populateBean(beanName, mbd, instanceWrapper);

接下来初始化bean

exposedObject = initializeBean(beanName, exposedObject, mbd);

现在分析这个初始化方法

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged(new PrivilegedAction<Object>() {
         @Override
         public Object run() {
            invokeAwareMethods(beanName, bean);
            return null;
         }
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      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()) {
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   return wrappedBean;
}

(1)调用invokeAwareMethods方法

if (System.getSecurityManager() != null) {
   AccessController.doPrivileged(new PrivilegedAction<Object>() {
      @Override
      public Object run() {
         invokeAwareMethods(beanName, bean);
         return null;
      }
   }, getAccessControlContext());
}
else {
   invokeAwareMethods(beanName, bean);
}

该方法如下

private void invokeAwareMethods(final String beanName, final Object bean) {
   if (bean instanceof Aware) {
      if (bean instanceof BeanNameAware) {
         ((BeanNameAware) bean).setBeanName(beanName);
      }
      if (bean instanceof BeanClassLoaderAware) {
         ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
      }
      if (bean instanceof BeanFactoryAware) {
         ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
   }
}

可以看到,如果bean实现了BeanNameAware接口,则调用setBeanName方法;如果实现了BeanFactoryAware接口,则调用setBeanFactory方法;

(2)接下来是第二块代码

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
   wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
      result = beanProcessor.postProcessBeforeInitialization(result, beanName);
      if (result == null) {
         return result;
      }
   }
   return result;
}

可以看到,会获得所有的BeanPostProcessor,遍历执行postProcessBeforeInitialization方法:即如果bean实现了BeanPostProcessor接口,Spring将调用它们的post- ProcessBeforeInitialization()方法; 如果返回null,则跳出循环。

(3)初始化

try {
   invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
   throw new BeanCreationException(
         (mbd != null ? mbd.getResourceDescription() : null),
         beanName, "Invocation of init method failed", ex);
}

查看invokeInitMethods方法

/**
 * Give a bean a chance to react now all its properties are set,
 * and a chance to know about its owning bean factory (this object).
 * This means checking whether the bean implements InitializingBean or defines
 * a custom init method, and invoking the necessary callback(s) if it does.
 * @param beanName the bean name in the factory (for debugging purposes)
 * @param bean the new bean instance we may need to initialize
 * @param mbd the merged bean definition that the bean was created with
 * (can also be {@code null}, if given an existing bean instance)
 * @throws Throwable if thrown by init methods or by the invocation process
 * @see #invokeCustomInitMethod
 */
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
      throws Throwable {
      //如果bean实现了InitializingBean接口,Spring将调用它们的after- PropertiesSet()方法
   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 {
         ((InitializingBean) bean).afterPropertiesSet();
      }
   }
//如果bean使用init-method声明了初始化方法,该方法也 会被调用
   if (mbd != null) {
      String initMethodName = mbd.getInitMethodName();
      if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
         invokeCustomInitMethod(beanName, bean, mbd);
      }
   }
}

注释里面已经很明白了:现在,给bena一个机会,它的属性都已设置,并且有机会了解工厂,检查bean是否实现了InitializingBean或定义了一个自定义的init方法,如果是,则调用必要的回调。

如果bean实现了InitializingBean接口,Spring将调用它们的after- PropertiesSet()方法。类似地,如果bean使用init-method声明了初始化方法,该方法也 会被调用;

(4)applyBeanPostProcessorsAfterInitialization与第二代码块一样,循环调用BeanPostProcessor的postProcessAfterInitialization方法
,如果返回null,则跳出循环

if (mbd == null || !mbd.isSynthetic()) {
   wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该 应用上下文被销毁;

如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样, 如果bean使用destroy-method声明了销毁方法,该方法也会被调用。

需要注意的是,spring只负责销毁单例的bean,多例的bean则不负责。

protected void destroyBeans() {
   getBeanFactory().destroySingletons();
}
public void destroy() {
   if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
      for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
         processor.postProcessBeforeDestruction(this.bean, this.beanName);
      }
   }

   if (this.invokeDisposableBean) {
      if (logger.isDebugEnabled()) {
         logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");
      }
      try {
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
               @Override
               public Object run() throws Exception {
                  ((DisposableBean) bean).destroy();
                  return null;
               }
            }, acc);
         }
         //如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法
         else {
            ((DisposableBean) bean).destroy();
         }
      }
      catch (Throwable ex) {
         String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
         if (logger.isDebugEnabled()) {
            logger.warn(msg, ex);
         }
         else {
            logger.warn(msg + ": " + ex);
         }
      }
   }
   //执行指定的销毁方法
   if (this.destroyMethod != null) {
      invokeCustomDestroyMethod(this.destroyMethod);
   }
   else if (this.destroyMethodName != null) {
      Method methodToCall = determineDestroyMethod();
      if (methodToCall != null) {
         invokeCustomDestroyMethod(methodToCall);
      }
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值