Spring源码(1):Spring Bean的生命周期

270 阅读4分钟

Bean的生命周期

Bean的生命周期主要分为4个阶段

  1. 实例化(Instantiation):实例化Bean对象
  2. 属性赋值(Populate):为Bean设置相关的属性和依赖
  3. 初始化(Initialization):包括Aware接口处理,BeanPostProcessor前置处理,InitializingBean接口处理,init-method方法执行,BeanPostProcessor后置处理
  4. 销毁(Destruction):

Bean的生命周期过程如图所示:

image.png

Bean的创建过程主要在AbstractAutowireCapableBeanFactory类中的doCreateBean()方法中实现:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {
   // 实例化Bean
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   
   // ...

   Object exposedObject = bean;
   try {
      // 属性赋值
      populateBean(beanName, mbd, instanceWrapper);
      // 初始化
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }

   // ...

   // 销毁-注册回调接口
   try {
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   }

   return exposedObject;
}

其中initializeBean()方法对应图中的3~7步,具体实现也是在AbstractAutowireCapableBeanFactory类中:

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

   // BeanPostProcessor前置处理
   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   // 实现了InitializingBean接口,调用afterPropertiesSet()方法
   // 若配置了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);
   }
   // BeanPostProcessor后置处理
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

// invokeInitMethods()同样也在AbstractAutowireCapableBeanFactory类中
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {
   // 判断是否实现了InitializingBean接口
   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();
      }
   }

   // 判断是否有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);
      }
   }
}

销毁的过程和初始化的过程类似,判断是否实现DisposableBean接口以及是否有实现destory-method方法

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

   // 若实现DisposableBean接口,则执行destory()方法
   if (this.invokeDisposableBean) {
      if (logger.isTraceEnabled()) {
         logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
      }
      try {
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
               ((DisposableBean) this.bean).destroy();
               return null;
            }, this.acc);
         }
         else {
            ((DisposableBean) this.bean).destroy();
         }
      }
   }

   // 配置了自定义的destory-method方法,则执行
   if (this.destroyMethod != null) {
      invokeCustomDestroyMethod(this.destroyMethod);
   }
   else if (this.destroyMethodName != null) {
      Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
      if (methodToInvoke != null) {
         invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
      }
   }
}

Bean初始化的扩展点

Aware接口

若Spring检测到bean实现了Aware接口,则会为其注入相应的依赖,通过让bean实现Aware接口,则能在bean中获得相应的Spring容器资源。Spring提供的Aware接口有:

  1. BeanNameAware:注入当前bean对应的beanName
  2. BeanClassLoaderAware:注入当前bean的ClassLoader
  3. BeanFactoryAware:注入当前BeanFactory容器的引用
private void invokeAwareMethods(String beanName, Object bean) {
   if (bean instanceof Aware) {
      if (bean instanceof BeanNameAware) {
         ((BeanNameAware) bean).setBeanName(beanName);
      }
      if (bean instanceof BeanClassLoaderAware) {
         ClassLoader bcl = getBeanClassLoader();
         if (bcl != null) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
         }
      }
      if (bean instanceof BeanFactoryAware) {
         ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
   }
}

Aware是知道的,已感知的意思,所以这些Aware接口时让实现接口的类可以感知到这些Aware接口获取的内容。例如BeanNameAware,实现了BeanNameAware接口,就可以让Bean感知到自身的BeanName,对应于Spring配置<bean id="xxx" class="xxx">中id属性

public interface BeanNameAware extends Aware {
   void setBeanName(String name);
}

BeanNameAware使用得具体实例:

  • 定义两个类,一个实现BeanNameAware,一个不实现BeanNameAware 实现BeanNameAware接口
public class ClassOne implements BeanNameAware {
    private String id;

    private String name;

    @Override
    public void setBeanName(String beanName){
        this.id = beanName;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString(){
        return "[id = "+this.id+", "+"name = "+this.name+"]";
    }
}

不实现BeanNameAware接口

public class ClassTwo {
    private String id;

    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString(){
        return "[id = "+this.id+", "+"name = "+this.name+"]";
    }
}
  • 两个类定义在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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="classOne" class="ClassOne">
        <property name="name" value="one"/>
    </bean>

    <bean id="classTwo" class="ClassTwo">
        <property name="name" value="one"/>
    </bean>
</beans>
  • 在测试类中获取该Bean,并打印具体的值
public class MyTest {
    @Test
    public void MyBean(){
        ApplicationContext context = new ClassPathXmlApplicationContext("application_context.xml");

        ClassOne classOne=context.getBean(ClassOne.class);
        System.out.println(classOne);

        ClassTwo classTwo=context.getBean(ClassTwo.class);
        System.out.println(classTwo);
    }
}

// 打印结果
[id = classOne, name = one]
[id = null, name = one]

BeanPostProcessor

BeanPostProcessor是Spring为修改Bean提供的强大扩展点,其可作用于容器的所有bean

public interface BeanPostProcessor {
   // 初始化前置处理
   default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }

   // 初始化后置处理
   default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }

}

InitializingBean和init-method

InitializingBean和init-method是Spring为bean初始化提供的扩展点。

可以在InitializingBean中的afterPropertiesSet()方法中写初始化逻辑

public interface InitializingBean {
   void afterPropertiesSet() throws Exception;
}

可以通过Spring-xml文件中指定bean的init-method方法

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="test" class="Test" init-method="init()"/>
    
</beans>

总结

  1. Spring Bean的生命周期主要有实例化,属性赋值,初始化,销毁4个阶段
  2. 初始化时,有Aware接口的依赖注入,BeanPostProcessor在初始化前后的处理,以及InitializingBean和init-method执行初始化操作