[译]10-Spring BeanPostProcessor
Spring框架提供了BeanPostProcessor接口,该接口暴露了两个方法postProcessBeforeInitialization(Object bean,String beanName)
和postProcessAfterInitialization(Object bean,String beanName).其中第一参数是经过实例化的bean实例,第二个参数是该bean在
spring IOC容器中的唯一标识.
通过实现BeanPostProcessor接口的postProcessBeforeInitialization和postProcessAfterInitialization方法,我们可以做很多有意义的
事情.postProcessBeforeInitialization方法的调用时机是在bean实例化并装配完毕之后,在调用初始化方法之前;而第二方法调用的时机
是在初始化方法调用之后.为了便于理解,我画了一张图:

通过上图可知,我们可以定义多个BeanPostProcessor接口的实现类,多个实现类直接以责任链的方式依次执行.
一般情况下BeanPostProcessor的实现类还会实现org.springframework.core.Ordered接口,Ordered接口的定义了getOrder方法,该方
法的返回值代表该BeanPostProcessor实现类的执行时机(数字越小,越先执行)
我们下面写一段例子程序,以上图为原本.程序中会定义三个BeanPostProcessor,三个的作用如下:
红色:LogRecorder,记录日志
蓝色:TimeRecoder,记录执行时间记录
紫色:PermissionCheck,权限检查
1.新建com.tutorialspoint.post_processor包,并在包中新建HelloWorld.java类,类的内容如下:
package com.tutorialspoint.post_processor;
public class HelloWorld {
public HelloWorld(){
System.out.println("constructor invoked ... ");
}
private String message;
public void setMessage(String message){
System.out.println("set method invoked ... ");
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
public void init(){
System.out.println("init method invoked ... ");
}
public void destroy(){
System.out.println("destroy method invoked ... ");
}
}
2.在包com.tutorialspoint.post_processor中新建上述三个BeanPostProcessor的实现类,三个类的内容分别如下:
LogRecorder.java
package com.tutorialspoint.post_processor; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered; public class LogRecorder implements BeanPostProcessor,Ordered { @Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
//初始化方法调用之后会回调该方法,在这里可以根据实际需求进行编码。
System.out.println("Log Info:"+beanName+" has been initailized");
return bean;
} @Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
//初始化方法调用之前调用该方法.
System.out.println("Log Info:"+beanName+" is going to be initailized");
return bean;
} //实现该方法用于指明该BeanPostProcessor的执行时机
@Override
public int getOrder() {
return 1;
} }
TimeRecoder.java
package com.tutorialspoint.post_processor; import java.util.Date; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered; public class TimeRecoder implements BeanPostProcessor,Ordered{ @Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println(beanName+" has been initilized,time now is "+new Date());
return bean;
} @Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println(beanName+" is going to be initilized,time now is "+new Date());
return bean;
} @Override
public int getOrder() {
return 2;
} }
PermissionCheck.java
package com.tutorialspoint.post_processor; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered; public class PermissionCheck implements BeanPostProcessor,Ordered { @Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println(beanName+" has been initailized,permissions checked... ");
return bean;
} @Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println(beanName+" is going to be initailized,begin to check permissions ... ");
return bean;
} @Override
public int getOrder() {
return 3;
} }
3.在src目录下新建post_processor.xml配置文件,文件内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="helloWorld"
class="com.tutorialspoint.post_processor.HelloWorld"
destroy-method="destroy"
init-method="init">
<property name="message" value="Hello World!"></property>
</bean> <!-- spring容器会检测到实现了BeanPostProcessor接口的bean,并在适当的时机调用适当的方法 -->
<bean name="logRecorder" class="com.tutorialspoint.post_processor.LogRecorder"></bean> <bean name="timeRecoder" class="com.tutorialspoint.post_processor.TimeRecoder"></bean> <bean name="permissionCheck" class="com.tutorialspoint.post_processor.PermissionCheck"></bean> </beans>
4.在com.tutorialspoint.post_processor包中新建MainApp.java,内容如下:
package com.tutorialspoint.post_processor; import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("post_processor.xml");
HelloWorld hw = (HelloWorld)ctx.getBean("helloWorld");
hw.getMessage();
ctx.registerShutdownHook();
}
}
5.运行程序,检查结果:

仔细分析运行结果,跟我们预期是一致的!
[译]10-Spring BeanPostProcessor的更多相关文章
- 译:Spring框架参考文档之IoC容器(未完成)
6. IoC容器 6.1 Spring IoC容器和bean介绍 这一章节介绍了Spring框架的控制反转(IoC)实现的原理.IoC也被称作依赖注入(DI).It is a process wher ...
- Spring框架系列(10) - Spring AOP实现原理详解之AOP代理的创建
上文我们介绍了Spring AOP原理解析的切面实现过程(将切面类的所有切面方法根据使用的注解生成对应Advice,并将Advice连同切入点匹配器和切面类等信息一并封装到Advisor).本文在此基 ...
- Spring 源码学习笔记10——Spring AOP
Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...
- 04 Spring:01.Spring框架简介&&02.程序间耦合&&03.Spring的 IOC 和 DI&&08.面向切面编程 AOP&&10.Spring中事务控制
spring共四天 第一天:spring框架的概述以及spring中基于XML的IOC配置 第二天:spring中基于注解的IOC和ioc的案例 第三天:spring中的aop和基于XML以及注解的A ...
- Spring BeanPostProcessor与动态加载数据源配置
前言: 本文旨在介绍Spring动态配置数据源的方式,即对一个DataSource的配置诸如jdbcUrl,user,password,driverClass都通过运行时指定,而非由xml静态配置定死 ...
- 10.Spring Bean的生命周期
Spring IOC容器可以管理Bean的生命周期,允许在Bean声明周期的特定点执行定制的任务. Spring IOC容器对Bean的生命周期进行管理的过程. 1.通过构造器或工厂方法创建Bean实 ...
- Spring 源码(8)Spring BeanPostProcessor的注册、国际化及事件发布机制
上一篇文章https://www.cnblogs.com/redwinter/p/16198942.html介绍了Spring的注解的解析过程以及Spring Boot自动装配的原理,大概回顾下:Sp ...
- 【译】Spring 4 基于TaskScheduler实现定时任务(注解)
前言 译文链接:http://websystique.com/spring/spring-job-scheduling-with-scheduled-enablescheduling-annotati ...
- 【译】Spring 4 + Hibernate 4 + Mysql + Maven集成例子(注解 + XML)
前言 译文链接:http://websystique.com/spring/spring4-hibernate4-mysql-maven-integration-example-using-annot ...
- 【译】Spring 4 自动装配、自动检测、组件扫描示例
前言 译文链接:http://websystique.com/spring/spring-auto-detection-autowire-component-scanning-example-with ...
随机推荐
- IBM带库加磁带操作
1.查询要弹出磁带的信息 可查询media日志,冻结,可用等,详情可查 查看带库空闲槽位 vmcheckxxx -rt tld -rn 0(0为带库名) 磁带详细信息: bpmedialist -m ...
- ImportError: No module named images
[问题] 在使用学习wxPython时,一个Dem抱有如题所示错误 [解决] images 只不过是wxpython自带demo中的一个文件 体验wxpython IN action的时候Import ...
- Linux中的/etc/nologin问题
/etc/nologin 文件给系统管理员提供了在 Linux 系统维护期间禁止用户登陆的方式. 如果系统中存在 /etc/nologin 文件那么普通用户登陆就会失败. 这是一种提高安全性和防止数据 ...
- 第9章 初识HAL固件库
本章参考资料:<STM32F76xxx参考手册>.<STM32F7xx规格书>.<Cortex-M3权威指南>, STM32 HAL库帮助文档:<STM32F ...
- jquery 添加和删除节点
// 增加一个三和一节点 function addPanel() { // var newPanel = $('.my-panel').clone(true) var newPanel = $(&qu ...
- iOS网络图片缓存详解
在开发移动应用的时候比如Android,IOS,因为手机流量.网速.内存等这些因素,当我们的移动应用是针对互联网,并要频繁访问网络的话,对网络优化这块就显得尤为重要了. 比如某个应用要经常显示网络图片 ...
- MySQL存储引擎MyISAM与InnoDB
一. MySQL存储引擎MyISAM与InnoDB如何选择 MySQL有多种存储引擎,每种存储引擎有各自的优缺点,可以择优选择使用:MyISAM.InnoDB.MERGE.MEMORY(HEAP).B ...
- 【MySQL】使用SQL语句操作MySQL
前言: MySQL在工作中是最常用的数据库,但在使用Django和Flask的时候,都是使用ORM进行操作,除了select语句外,其他的SQL语句操作MySQL的能力没有啥提高,为了解决这个问题, ...
- Mac中Mysql开启远程访问(不同于linux直接改配置文件)
在mac中安装Mysql Workbench 用root用户连上安装的Mysql. 开启远程访问的服务 如下图可以看到是root用户绑定的是localhost 如果不做修改的话,直接访问是访问不了 ...
- 内置函数系列之 filter
filter 过滤 基本语法: s = filter(function,iterable) 将可迭代对象的每一个元素,传进函数中,根据函数中的判断条件,返回True或False 返回True的是保留的 ...