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. Spring cloud微服务安全实战 最新完整教程

    课程资料获取链接:点击这里 采用流行的微服务架构开发,应用程序访问安全将会面临更多更复杂的挑战,尤其是开发者最关心的三大问题:认证授权.可用性.可视化.本课程从简单的API安全入手,过渡到复杂的微服务 ...

  2. lucas定理及其拓展的推导

    lucas定理及其拓展的推导 我的前一篇博客-- lucas定理 https://mp.csdn.net/mdeditor/100550317#主要是给出了lucas的结论和模板,不涉及推导. 本篇文 ...

  3. js内置对象的常用属性和方法(Array | String | Date | Math)

    js内置对象:Array  String  Math  Date <!DOCTYPE html> <html lang="en"> <head> ...

  4. 又一种获取redis cluster slots分布的小脚本

    需要:昨晚学习了cluster slots命令,之前写的脚本,有可以换种方法获取到redis cluster slots 分布情况. cluster slots的结果如下: 4 5460 5.5.5. ...

  5. mysql第五课

    修改表中一行或多行数据: SELECT*FROM student;+----+------+------+| id | name | ban  |+----+------+------+|  1 | ...

  6. Neo4j入门-开始使用

    前言 关系,指事物之间相互作用.相互影响的状态. 数据之间的关系也是如此,数据之间关系的存储在RDS就已经开始.从数据库支持的外键,到手动建立的关系表,人们采取了许多方法,只为了解决查询复杂.缓慢等问 ...

  7. .net 父类值赋给子类

    1.最简单的方式,反射+泛型 优点:字段修改时,无需更改代码,只需要更新实体即可 缺点:因为用到反射,可能效率会稍微弱那么一点点,没有实际用太多字段测试 public static cClass Pa ...

  8. Docker容器Centos不能使用systemctl命令问题

    注:本文出自博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 本文源链接:https://www.cnblogs.com/chloneda/p/bug-dock ...

  9. 同一服务器下发布两个不同网站(war包)的方法(这里采用的是二级域名的方法)

    这里是在阿里云服务器的上部署 在本地测试好之后,打包,然后发到服务器上的tomcat的webapp目录上(这个可能会有个bug,先启动下服务器,然后关掉,再启动,那个war包对应的文件才会出来) 这里 ...

  10. 剑指offer-面试题30-包含min函数的栈-栈

    /* 题目: 定义栈的数据结构,实现一个能够得到栈的最小元素的min函数. */ /* 思路: 错误思路:每次保存当前最小的元素,如果当前最小元素弹出,最小元素是谁? 正确思路:两个栈,一个栈保存数据 ...