1.BeanPostProcessor接口的介绍:

BeanPostProcessor是一个接口,其中有两个方法,postProcessBeforeInitialization和postProcessAfterInitialization两个方法,这两个方法分别是在spring容器中的bean初始化前后执行,所以spring容器中的每一个bean对象初始化前后,都会执行BeanPostProcessor接口的实现类的这两个方法。因此我们可以在每个bean对象初始化前后,加上自己的逻辑。实现方式:自定义一个BeanPostProcessor接口的实现类A,然后在类A的postProcessBeforeInitialization和postProcessAfterInitialization方法里面写上自己的逻辑。

看一下BeanPostProcessor接口的代码:

 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;
}
}
postProcessBeforeInitialization和postProcessAfterInitialization方法中的bean参数,就是将要初始化或已经初始化的spring容器中的bean对象。

2.如何证明spring容器中的bean对象初始化前后,都会执行BeanPostProcessor实现类的postProcessBeforeInitialization和postProcessAfterInitialization两个方法:
  a.首先spring中有一个类AbstractAutowireCapableBeanFactory
  b.展示AbstractAutowireCapableBeanFactory的三个个方法:spring容器初始化前后,都会执行它的applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization
   两个方法,而在这两个方法中都会遍历BeanPostProcessor的所有实现类,并分别执行BeanPostProcessor实现类的前置和后置方法。
     public List<BeanPostProcessor> getBeanPostProcessors() {
return this.beanPostProcessors;
} public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean; Object current;
//遍历所有的BeanPostProcessor实现类,spring容器中每个bean对象都要执行所有的BeanPostProcessor实现类的前置方法(postProcessBeforeInitialization)
for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
current = beanProcessor.postProcessBeforeInitialization(result, beanName);
if(current == null) {
return result;
}
} return result;
} public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean; Object current;
//遍历所有的BeanPostProcessor实现类,spring容器中每个bean对象都要执行所有的BeanPostProcessor实现类的后置方法(postProcessAfterInitialization)
for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
current = beanProcessor.postProcessAfterInitialization(result, beanName);
if(current == null) {
return result;
}
} return result;
}
写一个需求:
现在我有两个类分别是Dog和Bird,这两个类都有一个属性int类型age属性,现在我想把这两个类交给spring容器来管理,并在初始化时,让Dog的对象的age属性值为15,
让Bird的对象的age属性值为9. 
实现步骤:
  1.先写好Dog和Bird两个类:
 @Component
public class Bird { private int age; @Override
public String toString() {
return "Bird [age=" + age + "]";
}
}
 @Component
public class Dog { private int age;//狗一般活到15岁 @Override
public String toString() {
return "Dog [age=" + age + "]";
}
}

  2.然后在写一个类MyBeanPostProcessor实现bean后置处理器接口BeanPostProcessor:

 @Component
public class MyBeanPostProcessor implements BeanPostProcessor {
//在bean对象初始化之前被调用 bean是Spring容器管理一个对象,beanName就是当前对象在Spring容器中关联的key
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(bean.getClass()==Dog.class){
try{
Field field = bean.getClass().getDeclaredField("age");
field.setAccessible(true);
field.set(bean, 15);
}catch(Exception ex){
ex.printStackTrace();
}
}else if(bean.getClass()==Bird.class){
try{
Field field = bean.getClass().getDeclaredField("age");
field.setAccessible(true);
field.set(bean, 9);
}catch(Exception ex){
ex.printStackTrace();
}
}
return bean;
} //在bean对象初始化之后被调用 bean是Spring容器管理一个对象,beanName就是当前对象在Spring容器中关联的key
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
return bean;
}
}

  3.写个测试类来查看一下结果:

 public class TestMain {

     public static void main(String[] args) {
// 1.获得Spring容器对象
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
Dog dog = (Dog)context.getBean("dog");
System.out.println(dog);
Bird bird = (Bird)context.getBean("bird");
System.out.println(bird);
}
}

  4.输出结果:输出的结果满足需求。


1.spring源码-BeanPostProcessor后置处理器的更多相关文章

  1. 2.spring源码-BeanPostProcessor后置处理之ApplicationContextAwareProcessor,实现spring容器中某一个类的bean对象在初始化时需要得到Spring容器内容。

    需求:我们的需求是,在spring初始化完毕时,使我们自定义一个类Bird类可以得到spring容器内容. 实现步骤: 1.首先我们来看一下ApplicationContextAwareProcess ...

  2. Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理

    Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理 前言 上一篇分析了BeanFactoryPostProcessor的作用,那么这一篇继续 ...

  3. Spring之BeanPostProcessor(后置处理器)介绍

      为了弄清楚Spring框架,我们需要分别弄清楚相关核心接口的作用,本文来介绍下BeanPostProcessor接口 BeanPostProcessor   该接口我们也叫后置处理器,作用是在Be ...

  4. 【Spring注解驱动开发】关于BeanPostProcessor后置处理器,你了解多少?

    写在前面 有些小伙伴问我,学习Spring是不是不用学习到这么细节的程度啊?感觉这些细节的部分在实际工作中使用不到啊,我到底需不需要学习到这么细节的程度呢?我的答案是:有必要学习到这么细节的程度,而且 ...

  5. spring的组件工厂后置处理器——BeanFactoryPostProcessor

    作用和调用时机 spring有两种后置处理器: 1. 组件后置处理器——org.springframework.beans.factory.config.BeanPostProcessor: 2. 工 ...

  6. Spring容器中bean的生命周期以及关注spring bean对象的后置处理器:BeanPostProcessor(一个接口)

    Spring IOC 容器对 Bean 的生命周期进行管理的过程: 1.通过构造器或工厂方法创建 Bean 实例 2.为 Bean 的属性设置值和对其他 Bean 的引用 3.将 Bean 实例传递给 ...

  7. Spring的BeanPostProcessor后置处理器与bean的生命周期

    前言 本文将把Spring在Bean的生命周期中涉及到的后置处理器一一梳理出来,并简要说一下功能,至于每个后置处理器在实际扩展中的用处,还要后续慢慢探索总结. 正文 下面一步步跟进探寻那些后置处理器们 ...

  8. Spring中Bean的后置处理器

    以下内容引用自http://wiki.jikexueyuan.com/project/spring/bean-post-processors.html: Bean后置处理器 BeanPostProce ...

  9. BeanPostProcessor后置处理器原理以及ApplicationListener原理

    BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的 1.BeanFactoryPostProcessor:BeanFactory的后置处理器; 在Bean ...

随机推荐

  1. matlab中的输出显示函数

    matlab中的输出显示函数 在matlab中使用的显示函数有disp.sprintf.fprintf比较常用.下面来介绍一下他们的用法. 1.disp()函数: disp(x)主要是用来输出变量x的 ...

  2. MySQL 8 拷贝MySQL数据库到另一台机器

    通过mysqldump生成包含SQL语句的文件,然后将其应用到目标机器的mysql客户端程序. mysqldump --help 可以获取mysqldump选项以及用法. 如果源服务器上启用了GTID ...

  3. Flex布局如何实现最后一个元素右对齐,或者第一个元素左对齐

    先来看看一个例子 在一个div我们把四个按钮全部放到右边去了,看下效果↓ 这个时候我们想把第一个按钮左对齐,其他保持不变 这时候我们来个第一个按钮样式上加上 :margin-right: auto; ...

  4. CentOS7安装gotoblas遇到的问题

    1. 错误信息: /usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld: cannot find -l-l ...

  5. JN_0013:win10快速回桌面

    4.最后一种方法是最为实用的方法.按快捷键[windows键+D键],如下图所示,两键同时按,或者先按住windows键不放再按D键.这种方法在任何时候都是有用的,并且熟练使用后可以达到非常快的速度: ...

  6. ES6基础与解构赋值(高颜值弹框小案例!)

    let只作用在当前块级作用域内使用let或者const声明的变量,不能再被重新声明let不存在`变量提升` console.log(dad); var dad = '我是爸爸!';//预定义undef ...

  7. adb -- cannot connect to x.x.x.x:5555“由于目标计算机积极拒绝,无法连接”

    原因 安卓系统未打开adb网络调试功能 通过USB方式连接到安卓系统设置即可 解决 先通过USB线连接 adb devices 能看到所连接的设备情况下 adb root 权限提权 adb shell ...

  8. 嵊州D5T1 鸡翅 chicken

    鸡翅  chicken [问题描述] 小 x 非常喜欢小鸡翅. 他得知 NSC 超市为了吸引顾客,举行了如下的活动: 一旦有顾客在其他超市找到更便宜的小鸡翅, NSC 超市将免费送给顾客 1000g ...

  9. .net mvc 多文件上传

    1.input文件上传设置允许选择多个文件,设置属性 multiple即可 <input type="file" multiple="multiple" ...

  10. PAT (Basic Level) Practice (中文)1043 输出PATest (20 分)

    给定一个长度不超过 1 的.仅由英文字母构成的字符串.请将字符重新调整顺序,按 PATestPATest.... 这样的顺序输出,并忽略其它字符.当然,六种字符的个数不一定是一样多的,若某种字符已经输 ...