Spring中bean的生命周期

79 阅读2分钟

一、bean生命周期的概要

在Spring中bean的生命周期实际上就是阐述我们托由Spring容器管理bean对象的构建使用以及销毁的整个流程,其简单来说涵盖了四个阶段:

  1. 实例化:实例化bean实例
  2. 属性赋值:设置对象属性
  3. 初始化
    1. 检查Aware相关接口、设置依赖
    2. BeanPostProcessor前置处理
    3. InitilizingBean接口处理
    4. 自定义init-method配置处理
    5. BeanPostPorcessor后置处理
  4. 销毁
    1. DisposableBean接口自定义实现处理
    2. destory-method自定义处理

二、代码

所有的逻辑都集中放在AbstractAutowireCapableBeanFactory.doCreateBean()中

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {
      // 实例化bean实例
      instanceWrapper = createBeanInstance(beanName, mbd, args);
      
      try {
          //属性赋值
          populateBean(beanName, mbd, instanceWrapper);
          //初始化bean
          exposedObject = initializeBean(beanName, exposedObject, mbd);
      }
}

在初始化bean的方法initializeBean内部涵盖了bean的aware接口实现调用

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   // 检查Aware相关接口并设置相关依赖
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      // 调用BeanPostProcessor的前置方法
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      // 配置自定义的 init-method方法,则执行
      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()) {
      // 调用BeanPostProcessore后置方法
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

三、Spring预留扩展点

3.1 Aware接口

通过实现Aware接口,bean可以在Spring中获取相应的容器资源,Spring提供的Aware接口有

  1. BeanNameAware
  2. BeanClassLoaderAware
  3. BeanFactoryAware
private void invokeAwareMethods(String beanName, Object bean) {
   if (bean instanceof Aware) {
      // 注入bean的名称
      if (bean instanceof BeanNameAware) {
         ((BeanNameAware) bean).setBeanName(beanName);
      }
      // 注入bean的ClassLoader
      if (bean instanceof BeanClassLoaderAware) {
         ClassLoader bcl = getBeanClassLoader();
         if (bcl != null) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
         }
      }
      // 设置bean的BeanFactory
      if (bean instanceof BeanFactoryAware) {
         ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
   }
}

3.2 BeanPostProcessor

BeanPostProcessor是Spring为修改bean预留的一个扩展点,可作用于容器中的所有bean

public interface BeanPostProcessor {
   @Nullable
   // 前置处理
   default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }
   @Nullable
   // 后置处理
   default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }

}

常用使用场景

  1. 对于标记接口的实现类,进行自定义处理,如在ApplicationContextAwareProcessor,为其注入相应依赖
  2. 为当前对象提供代理实现,例如Spring AOP工农,生成对象代理类
// AbstractAutoProxyCreator.java
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
    if (targetSource != null) {
        if (StringUtils.hasLength(beanName)) {
            this.targetSourcedBeans.add(beanName);
        }
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
        Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
        this.proxyTypes.put(cacheKey, proxy.getClass());
        // 返回代理类
        return proxy;
    }

    return null;
}

3.3 InitializingBean和init-method

InitializingBean接口通过内部提供的afterPropertiesSet方法进行预留处理
init-method通过xml配置的形式进行预留处理