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. vue实现打印功能

    通过npm 安装插件 1.安装  npm install vue-print-nb --save 2.引入  安装好以后在main.js文件中引入 import Print from 'vue-pri ...

  2. python基礎學習第二天

    字符编码 # 需知:## 1.在python2默认编码是ASCII, python3里默认是unicode## 2.unicode 分为 utf-32(占4个字节),utf-16(占两个字节),utf ...

  3. es5和es6中如何处理不确定参数

    场景:求出不定参数的总数和 //利用arguments function sum () { let num = 0 //Array.prototype.forEach.call(arguments,f ...

  4. MySQL8.0远程连接和用户授权相关设置

    文章目录 1.开启MySQL远程连接 2.关闭MySQL远程连接 3.修改防火墙规则,开放端口 4.创建用户以及给用户授权 5.删除用户及权限 1.开启MySQL远程连接 mysql -u root ...

  5. 【剑指Offer】61、把二叉树打印成多行

    题目描述 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行. 题解一:BFS public static ArrayList<ArrayList<Integer>> ...

  6. WIFI Pineapple 排雷

    1.在WEB界面中无法安装插件 解决:进入SSH,执行opkg update 2.ettercap无法运行,缺少动态连接库,libpcap.so.1.3 创建软连接   ln -s /usr/lib/ ...

  7. Pikachu-SSRF(服务器端请求伪造)

    SSRF(Server-Side Request Forgery:服务器端请求伪造) 其形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,但又没有对目标地址做严格过滤与限制 导致攻击者可 ...

  8. Spark学习之路 (十二)SparkCore的调优之资源调优[转]

    概述 在开发完Spark作业之后,就该为作业配置合适的资源了.Spark的资源参数,基本都可以在spark-submit命令中作为参数设置.很多Spark初学者,通常不知道该设置哪些必要的参数,以及如 ...

  9. 【5】激活函数的选择与权值w的初始化

    激活函数的选择: 西格玛只在二元分类的输出层还可以用,但在二元分类中,其效果不如tanh,效果不好的原因是当Z大时,斜率变化很小,会导致学习效率很差,从而很影响运算的速度.绝大多数情况下用的激活函数是 ...

  10. 如何调试TaskPaper的JavaScript上下文?

    Mac 上的纯文本 GTD 工具TaskPaper for Mac(纯文本任务管理器)是一款适用于Mac操作系统的软件.如何调试TaskPaper的JavaScript上下文?[dl]15-1068[ ...