1.spring源码-BeanPostProcessor后置处理器
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后置处理器的更多相关文章
- 2.spring源码-BeanPostProcessor后置处理之ApplicationContextAwareProcessor,实现spring容器中某一个类的bean对象在初始化时需要得到Spring容器内容。
需求:我们的需求是,在spring初始化完毕时,使我们自定义一个类Bird类可以得到spring容器内容. 实现步骤: 1.首先我们来看一下ApplicationContextAwareProcess ...
- Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理
Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理 前言 上一篇分析了BeanFactoryPostProcessor的作用,那么这一篇继续 ...
- Spring之BeanPostProcessor(后置处理器)介绍
为了弄清楚Spring框架,我们需要分别弄清楚相关核心接口的作用,本文来介绍下BeanPostProcessor接口 BeanPostProcessor 该接口我们也叫后置处理器,作用是在Be ...
- 【Spring注解驱动开发】关于BeanPostProcessor后置处理器,你了解多少?
写在前面 有些小伙伴问我,学习Spring是不是不用学习到这么细节的程度啊?感觉这些细节的部分在实际工作中使用不到啊,我到底需不需要学习到这么细节的程度呢?我的答案是:有必要学习到这么细节的程度,而且 ...
- spring的组件工厂后置处理器——BeanFactoryPostProcessor
作用和调用时机 spring有两种后置处理器: 1. 组件后置处理器——org.springframework.beans.factory.config.BeanPostProcessor: 2. 工 ...
- Spring容器中bean的生命周期以及关注spring bean对象的后置处理器:BeanPostProcessor(一个接口)
Spring IOC 容器对 Bean 的生命周期进行管理的过程: 1.通过构造器或工厂方法创建 Bean 实例 2.为 Bean 的属性设置值和对其他 Bean 的引用 3.将 Bean 实例传递给 ...
- Spring的BeanPostProcessor后置处理器与bean的生命周期
前言 本文将把Spring在Bean的生命周期中涉及到的后置处理器一一梳理出来,并简要说一下功能,至于每个后置处理器在实际扩展中的用处,还要后续慢慢探索总结. 正文 下面一步步跟进探寻那些后置处理器们 ...
- Spring中Bean的后置处理器
以下内容引用自http://wiki.jikexueyuan.com/project/spring/bean-post-processors.html: Bean后置处理器 BeanPostProce ...
- BeanPostProcessor后置处理器原理以及ApplicationListener原理
BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的 1.BeanFactoryPostProcessor:BeanFactory的后置处理器; 在Bean ...
随机推荐
- Typora自动编号设置
找到C:\Users\用户名\AppData\Roaming\Typora\themes\路径下的base.user.css,用文本编辑器打开(若不存在,则自己创建一个),将一下内容复制进去,然后重启 ...
- 树莓派搭载CentOS7系统初始配置
系统属性: 树莓派型号:3b SD:32GB 系统:CentOS-Userland-7-armv7hl-RaspberryPI-Minimal-1908-sda.raw 开机配置: 连接树莓派: 配件 ...
- MySQL日志文件和InnoDB引擎文件简介
MySQL和InnoDB的关系不在这里介绍了.但是大家都知道其中相关的文件很多,类型很多.看文件名就有点分布清楚了.所以在这里简单介绍下他们的文件. 我们直接看文件列表以及在后面直接加注释.做笔记. ...
- python生日贺卡制作以及细节问题的解决最后把python项目发布为exe可执行程序过程
自己今天第一次做一个python生日贺卡: 效果图 参考之前有位大佬的作品,自己稍微的改造了一下下 首先:上程序 Birthday.py """ ----------- ...
- Dictionary的基本用法
1.创建泛型哈希表,然后加入元素 Dictionary<string,string> openWith=new Dictionary<string, string>(); op ...
- Windows显示默认桌面图标(计算机,用户的文件,网络,控制面板,回收站)
1.按Win+R 2.复制以下命令 rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,0 3.点击运行,根据需求勾选相应图标即可
- echarts 【图表的基本使用】
一.柱状图 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <tit ...
- ssh 或 putty 连接linux报错解决方法
由于当天多次输入错误密码,ssh和putty就连接不上了,纠结了很久解决问题 ssh连接提示错误:server unexpectedly closed network connection putty ...
- Centos 安装SVN
Centos 安装SVN centos(我这里使用的是CentOS7)下yum命令即可方便的完成安装 $ sudo yum install subversion 测试安装是否成功: $ svnser ...
- Milestone
为什么开博客? 事情要从一只蝙蝠说起... 准备用博客做什么? 记录自己在开发中遇到的issue以及解决的思路:记录一些读书笔记以便温故:练习如何制造仪式感,ect. ...