[译]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 ...
随机推荐
- selenium 打开浏览器报错java.lang.NoSuchMethodError: org.openqa.selenium.chrome.ChromeOptions.addArguments([Ljava/lang/String;)
java.lang.NoSuchMethodError: org.openqa.selenium.chrome.ChromeOptions.addArguments([Ljava/lang/Strin ...
- 创建一个gradle项目
1.创建项目 一定要选这个安装的路径 项目创建成功,修改build.gradle文件,主要是为了下载依赖的jar包,原始模板, 而我修改之后,如下 apply plugin: 'idea' apply ...
- Kruskal算法求最小生成树(POJ2485)
题目链接:http://poj.org/problem?id=2485 #include <iostream> #include <stdio.h> #include < ...
- VPS一键测试脚本 / 自带结果导出
脚本命令 一下脚本可能卡住,运行时间长,建议在screen中运行. 1.秋水逸冰大佬的Bench.sh脚本 特点:用时较短,对系统测试全面,英文:但缺少国内节点测速 有趣的是,bench.sh既是脚本 ...
- 剑指offer25 二叉树中和为某一直的路径
先序遍历 class Solution { public: vector<vector<int> > FindPath(TreeNode* root,int expectNum ...
- 【转】Spring 整合 Quartz 实现动态定时任务
http://blog.csdn.net/u014723529/article/details/51291289 最近项目中需要用到定时任务的功能,虽然spring 也自带了一个轻量级的定时任务实现, ...
- .clone事件当你克隆的时候,DOM节点是克隆出来了,但是克隆出来的节点不能运行时事件 ...
解决办法如下在clone()里面加个参数true,即可完成事件的植入.即:.clone(true).clone( [ withDataAndEvents ], [ deepWithDataAndEve ...
- Linux内存管理 —— 内核态和用户态的内存分配方式
1. 使用buddy系统管理ZONE我的这两篇文章buddy系统和slab分配器已经分析过buddy和slab的原理和源码,因此一些细节不再赘述.所有zone都是通过buddy系统管理的,buddy ...
- URL中传递JSON数据
有关于JSON如何在前后之间进行传递,转换成对象等操作,请查看 C#Json数据交互 (这篇文章主要介绍了如何转化Json格式的数据,以及如何使用) 我们在URL中传递数据一般都是 XX.asp ...
- Pop–实现任意iOS对象的任意属性的动态变化
简介 Pop 是一个可扩展的动画引擎,可用于实现任意iOS对象的任意属性的动态变化,支持一般动画,弹性动画和渐变动画三种类型. 项目主页: pop 最新示例: 点击下载 注意: 官方代码中,并不包含实 ...