BeanPostProcessor我们一般称为Bean的后置处理器,它与我们前面介绍的InitialingBeaninit-method等一样,都是在bean的初始化时被调用,具体的用法我们在举例中进行学习。

要使用BeanPostProcessor非常简单,只要实现这个接口即可。

在此之前,我们来先看下我们的Cat类,我们的目的是将这个Cat注册进spring的ioc容器中,并让这个BeanPostProcessor起到作用。

public class Cat implements InitializingBean,DisposableBean {

	public Cat(){
System.out.println("cat constructor...");
} @Override
public void destroy() throws Exception {
// TODO Auto-generated method stub
System.out.println("cat...destroy...");
} @Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
System.out.println("cat...afterPropertiesSet...");
} //对象创建并赋值之后调用
@PostConstruct
public void initMethod(){
System.out.println("Cat....@PostConstruct...");
} //容器移除对象之前
@PreDestroy
public void detoryMethod(){
System.out.println("Cat....@PreDestroy...");
} public void initCat() {
System.out.println("Cat.initCat()......");
} public void cleanup() {
System.out.println("Cat.cleanup()......");
}
}

再来看下我们的配置类

@Configuration
public class MainConfigOfLifeCycle { // @Scope("prototype")
@Bean(initMethod="initCat",destroyMethod="cleanup")
public Cat cat(){
return new Cat();
} @Bean
public MyBeanPostProcessor myBeanPostProcessor() {
return new MyBeanPostProcessor();
}
}

结合之前学习过的内容, 就能知道我们为这个Cat类应用了三种初始化及销毁方法,

分别是@PostConstruct@Predestroy

还有就是实现 InitializingBean,DisposableBean这两个接口的afterPropertiesSet()destro()方法

另外就是标注在@Bean(initMethod="initCat",destroyMethod="cleanup")定义的两个方法,也存在于Cat类中,


现在我们就要加入BeanPostProcessor

/**
* 后置处理器:初始化前后进行处理工作
* 将后置处理器加入到容器中,只需要继承BeanPostProcessor接口并实现其两个方法即可。
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor { @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
return bean;
} @Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
return bean;
} }

现在一切具备,再写一个测试方法:

	@Test
public void test01(){
//1、创建ioc容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器创建完成..."); //applicationContext.getBean("car");
//关闭容器
applicationContext.close();
}

观察控制台打印结果

cat constructor...// 创建cat对象
postProcessBeforeInitialization...cat=>com.atguigu.bean.Cat@6591f517 //在所有初始化方法之前被调用
Cat....@PostConstruct...
cat...afterPropertiesSet...
Cat.initCat()......
postProcessAfterInitialization...cat=>com.atguigu.bean.Cat@6591f517// 在所有初始化方法之后被调用
容器创建完成...
Cat....@PreDestroy...// 销毁方法不需要关注
cat...destroy...
Cat.cleanup()......

通过上面这个例子,已经很显然BeanPostProcessor的用法,它是在容器中bean初始化前后被调用。


源码调用分析:

我们在eclipse中启用debug模式,

看看这个方法的源码,直接在方法注释中进行分析

	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()) {
// 初始化前调用BeanPostProcessor
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()) {
// 初始化后调用BeanPostProcessor
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}

就看到这里,里面内容比较多,可以进invokeInitMethods看看几个初始化方法的调用顺序,JSR-250注解@PostConstruct是如何起作用的等等 ,我们这里只是来源码中找找它在源码中的位置。


又是一个夜晚,一船的清梦。

八、spring生命周期之BeanPostProcessor的更多相关文章

  1. spring生命周期

    Github地址 最近在整合mybatis-spring. 公司里面已经有一个叫做kylin-datasource的开发包,以前能够提供master和slave2个数据源,最近更新了2.0版本,支持自 ...

  2. 说下spring生命周期

    面试官:说下spring生命周期 程序员:不会 那你先回去等消息吧     Bean实现了BeanNameAware,Spring会将Bean的ID透传给setBeanName java.后端开发.程 ...

  3. Spring生命周期详解

    导读 Spring中Bean的生命周期从容器的启动到停止,涉及到的源码主要是在org.springframework.context.support.AbstractApplicationContex ...

  4. 【源码】spring生命周期

    一.spring生命周期 1. 实例化Bean 对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用crea ...

  5. Spring学习总结(4)-Spring生命周期的回调

    参考文档:https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans ...

  6. spring源码学习(四)-spring生命周期用到的后置处理器

    生命周期的九大后置处理器 第一次调用后置处理器org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory# ...

  7. Spring生命周期 Constructor > @PostConstruct > InitializingBean > init-method

    项目中用到了 afterPropertiesSet: 于是具体的查了一下到底afterPropertiesSet到底是什么时候执行的.为什么一定要实现 InitializingBean; **/ @C ...

  8. spring 生命周期最详解

    转载. https://blog.csdn.net/qq_23473123/article/details/76610052 目的 在大三开始学习spring时,老师就说spring bean周期非常 ...

  9. spring生命周期流程图

    Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring ...

随机推荐

  1. LeetCode 855. Exam Room

    原题链接在这里:https://leetcode.com/problems/exam-room/ 题目: In an exam room, there are N seats in a single ...

  2. php正则表示中的元字符

    元字符 抛出问题: \d 代表匹配一个字符.而我现在想要匹配十个八个,任意多个数字肿么办? 这个时候我们就要用到元字符.在使用原子的时候,发现只能够匹配一个字符,可是要匹配多个字符就出现了问题.大理石 ...

  3. OKR如何解决策略执行问题

    卡普兰和诺顿在2005年发现,十分之九的组织未能执行其战略. 唐纳德·萨尔(Donald Sull)在2015年的研究中发现,有45%的中层管理人员甚至无法说出其组织的重中之重.这些中层经理基本上负责 ...

  4. 3-开发共享版APP(接入指南)-设备接入说明:使用隐藏配置

    https://www.cnblogs.com/yangfengwu/p/11273226.html 该APP安装包下载链接: http://www.mnif.cn/appapk/IotDevelop ...

  5. 安卓入门教程(十五)- Fragment,Service,WAMP下载

    Fragment概述 Fragment可以被嵌入到Activity中,一个Activity可以有多个Fragment. 创建Fragment public class MyFragment exten ...

  6. php . extension_loaded

    (PHP 4, PHP 5, PHP 7) extension_loaded — 检查一个扩展是否已经加载 如果 name 指定的扩展已加载,返回TRUE,否则返回 FALSE. Example #1 ...

  7. 富文本编辑器kindeditor的使用

    第一步:导入前端js文件 <!-- 富文本编辑器 --> <link rel="stylesheet" href="../plugins/kindedi ...

  8. element ui 怎么去修改el-date-picker的时间

    <el-date-picker v-model="formSearch.timeRange" type="daterange" placeholder=& ...

  9. centos7安装mysql8 ERROR! The server quit without updating PID file

    原因mysql的安装目录在/etc/my.cnf配置不正确或者目录中的文件没有权限导致的,或者日志目录没有权限导致的 使用chwon -R mysql:mysql  mysql的日志目录后重启mysq ...

  10. clion 查看代码 多次查看后如何一步一步回退到最初查看的代码位置

    在settings->keymap里面搜索navigate,然后就有蓝色字体的Back.Forward,这个两个有自己对应的快捷键,但是你有可能不能使用这个功能,因为在不同的操作系统里面,有可能 ...