第4章 容器

4.5 Bean的生命周期

  面试必问的问题

  • bean的生命周期
  • bean的生命周期由谁管理
  • 单例和原型模式下生命周期的区别

4.5.1 BeanFactory中Bean的生命周期

  BeanFactory是一个接口,这里BeanFactory生命周期的分析是和下面的ApplicationContext的生命周期相对应的。

  

  很长,不想看。按照Bean对象的行为可以用这三个时间点切分:1、Bean对象创建 2、Bean对象属性注入 3、Bean对象销毁

  中所周期BeanFactory采用懒加载机制,Bean只有在第一次使用的时候才被创建。在Bean对象创建前,如果容器里注册了实现InstantiationAwareBeanPostProcessor接口的类,那么在Bean创建前会执行postProcessBeforeInstantiation方法。这个接口的名字有点奇怪,BeanPostProcessor好像是在Bean被创建之后才调用的方法但明明有一个是Bean创建前调用的方法。

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    Object postProcessBeforeInstantiation(Class<?> var1, String var2) throws BeansException;

    boolean postProcessAfterInstantiation(Object var1, String var2) throws BeansException;

    PropertyValues postProcessPropertyValues(PropertyValues var1, PropertyDescriptor[] var2, Object var3, String var4) throws BeansException;
}

  在为Bean注入属性之前,还要执行上面这个接口的postProcessAfterInstantiation方法。这个名字就比较合适了,After Befor很清晰。这个接口最后一个方法postProcessPropertyValues是在设置每个属性之前调用的。这个接口的全家桶在设置属性前会被全部调用,然后会为Bean设置属性值。

  走到这里Bean已经被创建好且初始化完毕了,剩下的内容是针对Bean实现了特定的接口做出的特殊的处理,InstantiationAwareBeanPostProcessor全家桶是注册在容器里的,可以理解为全部的Bean初始化都要走InstantiationAwareBeanPostProcessor的逻辑。

  首先是BeanXXXXAware接口,实现了BeanNameAware接口的Bean能知道自己在Bean容器的名字,实现了BeanFactoryAware接口的Bean能够获得BeanFactory实例。

  接下来是BeanPostProcessor全家桶,这个名字和注册在容器里的InstantiationAwareBeanPostProcessor名字很像,InstantiationAwareBeanPostProcessor是BeanPostProcessor的子接口。首先调用的是BeforXXXX的方法,这个方法用于改变Bean对象,即在Bean对象被初始化完成属性注入完成后我们依然可以有机会改变他,Object var1就是需要改变的Bean对象,返回的是改变后的Bean对象,大名鼎鼎的Aop就是在这里实现的。在执行AfterXXX之前,如果Bean实现了initalizingBean接口则调用afterPropertiesSert。如果在配置文件里配置了init-method方法则会执行方法注入。然后就调用postProcessAfterInitialization方法。

public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;

    Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}

  到这里所有可以实现的接口、所有特殊的注入都检查完毕了。如果scope是singleton,就把bean放到缓存里,然后返回给调用者;如果是prototype就直接返回给调用者,Spring不在负责prototype的Bean的声明管理。

  容器只会负责singleton的Bean的后续生命管理,体现在两个地方,在容器关闭的时候,如果Bean实现了DisposableBean接口那么调用的destory方法;如果在xml里配置了destory-method属性则调用该方法。

 

posted @ 2019-02-25 11:01  AshOfTime  阅读(126)  评论(0编辑  收藏  举报