spring-bean的统一前后置处理器BeanPostProcessor原理

Bean的生命周期

bean的生命周期指bean 的创建 ->初始化 -> 销毁的过程
我们可以自定义 bean初始化和销毁 方法: 容器在bean进行到当前生命周期的时候, 来调用自定义的初始化和销毁方法。

bena的生命周期

public class Cat {
    public Cat() {
        System.out.println("Cat .......contract......");
    }

    /**
     * bena 初始化
     */
    public void init() {
        System.out.println("Cat .......init......");
    }

    /**
     * bena 销毁
     */
    public void destroy() {
        System.out.println("Cat .......destroy......");

    }

}


@Configuration
@ComponentScan("com.sjx.cap3.bean")
public class BeanLifeConfig {
//spring-bean生命周期之初始化和销毁的三种方式
//(1)注解bean之指定init-method/destroy-method
//(2)实现InitializingBean/DisposableBean接口
//(3)@PostConstruct和@PreDestroy注解
//本文采用第2种
    @Bean(initMethod = "init", destroyMethod = "destroy")
    public Cat cat() {
        return new Cat();
    }
}

测试

public class BeanLifeTest {
    @Test
    public void lifeTest() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanLifeConfig.class);
        System.out.println("容器初始化完成!");
        context.close();
    }
}

结果


image.png

当依次调用了bena 的构造方法、初始化方法、和销毁的方法。此结果印证了前面说的bean的生命周期。

BeanPostProcessor

BeanPostProcessor类可以让我们早Bean的初始化之前后进行后置处理。
下面通过代码验证一下。
在 com.sjx.cap3.bean包下 新建后置类

@Component
public class BeanPostProcessorTest  implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //返回一个的对象(传过来的对象)
        //在初始化方法调用之前进行后置处理工作,
        //什么时候调用它: init-method=init之前调用
        System.out.println("postProcessBeforeInitialization...."+beanName+"..."+bean);
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization...."+beanName+"..."+bean);
        return bean;
    }
}
image.png

从结果中我们可以看到初始化方法前后分别调用了处理器的两个方法。
下面我们分析一下 BeanPostProcessor源码


image.png
image.png
image.png
image.png
image.png

在这里我们可以拿到已经加载完成的处理器其中我们注入对象最常用的@Autowired 注解也在这个里面。


image.png
image.png

看看它是如何获取bean的

image.png
image.png

我们定义的Cat bean出现了。


image.png
image.png
image.png
image.png
image.png
image.png

至此通过前置和后置处理器完成了对bean的增强,总结一下大概得流程

可从容器类跟进顺序为:
AnnotationConfigApplicationContext-->refresh()-->
finishBeanFactoryInitialization(beanFactory)--->
beanFactory.preInstantiateSingletons()-->
getBean(beanName)--->
doGetBean(name, null, null, false)-->
createBean(beanName, mbd, args)-->
doCreateBean(beanName, mbdToUse, args)-->
createBeanInstance(beanName, mbd, args)(完成bean创建)-->
populateBean(beanName, mbd, instanceWrapper)(属性赋值)-->
行initializeBean(beanName, exposedObject, mbd)(Bean初始化)->
后置处理器完成对init方法的前后处理.

最终得到如下如下
createBeanInstance(beanName, mbd, args)(完成bean创建)
populateBean(beanName, mbd, instanceWrapper); 给bean进行属性赋值
initializeBean() //初始化Bean方法内容如下,后置处理器对init方法的前后处理
{
  applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  invokeInitMethods(beanName, wrappedBean, mbd) //执行自定义初始化
  applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)
}
从以上分析不难发现,bean的生命周期为bean的创建, 初始化, 当容器关闭时对单实例的bean进行销毁.

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容