spring学习四:Spring中的后置处理器BeanPostProcessor
BeanPostProcessor接口作用:
如果我们想在Spring容器中完成bean实例化、配置以及其他初始化方法前后要添加一些自己逻辑处理。我们需要定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IoC容器中。

package com.test.spring; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* bean后置处理器
* @author zss
*
*/
public class PostProcessor implements BeanPostProcessor { @Override
public Object postProcessBeforeInitialization(Object bean,
String beanName) throws BeansException {
if ("narCodeService".equals(beanName)) {//过滤掉bean实例ID为narCodeService
return bean;
}
System.out.println("后置处理器处理bean=【"+beanName+"】开始");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return bean;
} @Override
public Object postProcessAfterInitialization(Object bean,
String beanName) throws BeansException {
if ("narCodeService".equals(beanName)) {
return bean;
}
System.out.println("后置处理器处理bean=【"+beanName+"】完毕!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return bean;
} }
注意:接口中两个方法不能返回null,如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bena实例对象
因为后置处理器从Spring IoC容器中取出bean实例对象没有再次放回IoC容器中

将Spring的后置处理器PostProcessor配置到Spring配置文件中

<?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.xsd"> <!-- 定义一个bean -->
<bean id="narCodeService" class="com.test.service.impl.NarCodeServiceImpl">
</bean>
<bean id="beanLifecycle" class="com.test.spring.BeanLifecycle" init-method="init" destroy-method="close">
<property name="name" value="张三"></property>
<property name="sex" value="男"></property>
</bean> <!-- Spring后置处理器 -->
<bean id="postProcessor" class="com.test.spring.PostProcessor"/>
</beans>

BeanPostProcessor API:

public interface BeanPostProcessor {
/**
* Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
*/
//实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/**
* Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
*/
//实例化、依赖注入、初始化完毕时执行
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

由API可以看出:
1.后置处理器的postProcessorBeforeInitailization方法是在bean实例化,依赖注入之后及自定义初始化方法(例如:配置文件中bean标签添加init-method属性指定Java类中初始化方法、 @PostConstruct注解指定初始化方法,Java类实现InitailztingBean接口)之前调用
2:后置处理器的postProcessorAfterInitailization方法是在bean实例化、依赖注入及自定义初始化方法之后调用
注意: BeanFactory和ApplicationContext两个容器对待bean的后置处理器稍微有些不同。ApplicationContext容器会自动检测Spring配置文件中那些bean所对应的Java类实现了BeanPostProcessor 接口,并自动把它们注册为后置处理器。在创建bean过程中调用它们,所以部署一个后置处理器跟普通的bean没有什么太大区别。
2.BeanFactory容器注册bean后置处理器时必须通过代码显示的注册,在IoC容器继承体系中的ConfigurableBeanFactory接口中定义了注册方法

/**
* Add a new BeanPostProcessor that will get applied to beans created
* by this factory. To be invoked during factory configuration.
* <p>Note: Post-processors submitted here will be applied in the order of
* registration; any ordering semantics expressed through implementing the
* {@link org.springframework.core.Ordered} interface will be ignored. Note
* that autodetected post-processors (e.g. as beans in an ApplicationContext)
* will always be applied after programmatically registered ones.
* @param beanPostProcessor the post-processor to register
*/
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);

Spring如何调用多个BeanPostProcessor实现类:
我们可以在Spring配置文件中添加多个BeanPostProcessor(后置处理器)接口实现类,在默认情况下Spring容器会根据后置处理器的定义顺序来依次调用。
Spring配置文件:

<?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.xsd">
<!-- bean定义 -->
<bean id="narCodeService" class="com.test.service.impl.NarCodeServiceImpl">
</bean>
<bean id="postProcessor" class="com.test.spring.PostProcessor"/>
<bean id="postProcessorB" class="com.test.spring.PostProcessorB"/>
</beans>

BeanPostProcessor实现类:

package com.test.spring; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* bean后置处理器
* @author zss
*
*/
public class PostProcessor implements BeanPostProcessor { @Override
public Object postProcessBeforeInitialization(Object bean,
String beanName) throws BeansException {
System.out.println("后置处理器处理bean=【"+beanName+"】开始");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return bean;
} @Override
public Object postProcessAfterInitialization(Object bean,
String beanName) throws BeansException {
System.out.println("后置处理器处理bean=【"+beanName+"】完毕!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return bean;
}
}
----------------------------------------------------------------------------------------------------------------------------------------
package com.test.spring; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; public class PostProcessorB implements BeanPostProcessor { @Override
public Object postProcessBeforeInitialization(Object bean,
String beanName) throws BeansException {
System.out.println("后置处理器开始调用了");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return bean;
} @Override
public Object postProcessAfterInitialization(Object bean,
String beanName) throws BeansException {
System.out.println("后置处理器调用结束了");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return bean;
}
}

测试:

package com.test.spring; import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class T {
AbstractApplicationContext applicationcontext=null;
@Before
public void before() {
System.out.println("》》》Spring ApplicationContext容器开始初始化了......");
applicationcontext= new ClassPathXmlApplicationContext(new String[]{"test1-service.xml"});
System.out.println("》》》Spring ApplicationContext容器初始化完毕了......");
}
@Test
public void test() {
applicationcontext.registerShutdownHook();
}
}

测试结果:

》》》Spring ApplicationContext容器开始初始化了......
2017-03-19 10:50:29 INFO:ClassPathXmlApplicationContext-Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@18c92ff9: startup date [Sun Mar 19 10:50:29 CST 2017]; root of context hierarchy
2017-03-19 10:50:29 INFO:XmlBeanDefinitionReader-Loading XML bean definitions from class path resource [test1-service.xml]
后置处理器处理bean=【narCodeService】开始
后置处理器开始调用了
后置处理器处理bean=【narCodeService】完毕!
后置处理器调用结束了
》》》Spring ApplicationContext容器初始化完毕了......
2017-03-19 10:50:34 INFO:ClassPathXmlApplicationContext-Closing org.springframework.context.support.ClassPathXmlApplicationContext@18c92ff9: startup date [Sun Mar 19 10:50:29 CST 2017]; root of context hierarchy

在Spring机制中可以指定后置处理器调用顺序,通过让BeanPostProcessor接口实现类实现Ordered接口getOrder方法,该方法返回一整数,默认值为 0,优先级最高,值越大优先级越低
例如:

package com.test.spring; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
/**
* bean后置处理器
* @author zss
*
*/
public class PostProcessor implements BeanPostProcessor,Ordered{ @Override
public Object postProcessBeforeInitialization(Object bean,
String beanName) throws BeansException {
System.out.println("后置处理器处理bean=【"+beanName+"】开始");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return bean;
} @Override
public Object postProcessAfterInitialization(Object bean,
String beanName) throws BeansException {
System.out.println("后置处理器处理bean=【"+beanName+"】完毕!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return bean;
} @Override
public int getOrder() {
return 1;
}
}
----------------------------------------------------------------------------
package com.test.spring; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered; public class PostProcessorB implements BeanPostProcessor,Ordered { @Override
public Object postProcessBeforeInitialization(Object bean,
String beanName) throws BeansException {
System.out.println("后置处理器开始调用了");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return bean;
} @Override
public Object postProcessAfterInitialization(Object bean,
String beanName) throws BeansException {
System.out.println("后置处理器调用结束了");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return bean;
} @Override
public int getOrder() {
return 0;
}
}

测试结果:
》》》Spring ApplicationContext容器开始初始化了......
2017-03-19 11:04:10 INFO:ClassPathXmlApplicationContext-Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@18c92ff9: startup date [Sun Mar 19 11:04:10 CST 2017]; root of context hierarchy
2017-03-19 11:04:10 INFO:XmlBeanDefinitionReader-Loading XML bean definitions from class path resource [test1-service.xml]
后置处理器开始调用了
后置处理器处理bean=【narCodeService】开始
后置处理器调用结束了
后置处理器处理bean=【narCodeService】完毕!
》》》Spring ApplicationContext容器初始化完毕了......
2017-03-19 11:04:14 INFO:ClassPathXmlApplicationContext-Closing org.springframework.context.support.ClassPathXmlApplicationContext@18c92ff9: startup date [Sun Mar 19 11:04:10 CST 2017]; root of context hierarchy
源自:https://www.cnblogs.com/sishang/p/6576665.html
spring学习四:Spring中的后置处理器BeanPostProcessor的更多相关文章
- Spring点滴五:Spring中的后置处理器BeanPostProcessor讲解
BeanPostProcessor接口作用: 如果我们想在Spring容器中完成bean实例化.配置以及其他初始化方法前后要添加一些自己逻辑处理.我们需要定义一个或多个BeanPostProcesso ...
- Spring中的后置处理器BeanPostProcessor讲解
Spring中提供了很多PostProcessor供开发者进行拓展,例如:BeanPostProcessor.BeanFactoryPostProcessor.BeanValidationPostPr ...
- spring源码学习(四)-spring生命周期用到的后置处理器
生命周期的九大后置处理器 第一次调用后置处理器org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory# ...
- spring中Bean后置处理器实现总结
BeanPostProcessor接口 bean的后置处理器实现功能主要是 可以在bean初始化之前和之后做增强处理.自定义MyBeanProcessor实现BeanPostProcessor接口,重 ...
- Spring的后置处理器BeanPostProcessor
一.BeanPostProcessor接口的作用 如果我们需要在Spring容器完成Bean的实例化.配置和其他的初始化前后添加一些自己的逻辑处理,我们就可以定义一个或者多个BeanPostProce ...
- spring后置处理器BeanPostProcessor
BeanPostProcessor的作用是在调用初始化方法的前后添加一些逻辑,这里初始化方法是指在配置文件中配置init-method,或者实现了InitializingBean接口的afterPro ...
- Spring Bean的生命周期、后置处理器、定义继承
目录: 了解Spring的基本概念 Spring简单的示例 Spring Bean的定义及作用域 1.Bean的生命周期 Bean的生命周期可以简单的理解为:Bean的定义——Bean的初始化——Be ...
- spring的后置处理器——BeanPostProcessor以及spring的生命周期
后置处理器的调用时机 BeanPostProcessor是spring提供的接口,它有两个方法——postProcessBeforeInitialization.postProcessAfterIni ...
- Bean后置处理器 BeanPostProcessor
1.BeanPostProcessor接口的作用 Bean后置处理器允许在调用初始化方法前后对Bean进行额外的处理,Bean后置处理器对IOC容器的所有bean实例逐一处理,而非单一实例. 我们可以 ...
随机推荐
- CSS实现鼠标移入时图片的放大效果以及缓慢过渡
transform:scale()可以实现按比例放大或者缩小功能. transition可以设置动画执行的时间,实现缓慢或者快速的执行动画,效果图如下: 源码: <!DOCTYPE html&g ...
- Chapter 4 Effect Modification
目录 4.1 Definition of effect modification 4.2 Stratification to identify effect modification 4.3 Why ...
- Capstone代商|Capstone代理商|Capstone选型
Capstone专注于USB typec .Displaypor.hdmi.VGA.LVDS.MIPI 等端口音视频数据转换方案芯片的设计与开发,Capstone品牌起源于中国台湾,Capstone科 ...
- Java初学者作业——编写Java程序,根据输入的某个班级的学员成绩,计算该班级学员的平均成绩,要求输入班级的人数。
返回本章节 返回作业目录 需求说明: 编写Java程序,根据输入的某个班级的学员成绩,计算该班级学员的平均成绩,要求输入班级的人数. 实现思路: 声明变量sum.count以及avg用于存储总成绩.班 ...
- 你在寻找Vue3移动端项目框架嘛?请看这里
现在web开发变得更加美妙高效,在于开发工具设计得更好了,丰富性与易用性,都有所提高.丰富性带来了一个幸福的烦恼,就是针对实际应用场景,如何选择工具 ? 1. Vue Cli和Vite之间的选择 Vi ...
- 从0开始手把手带你入门Vue3-全网最全(1.1w字)
天命不足畏,祖宗不足法. --王安石 前言 本文并非标题党,而是实实在在的硬核文章,如果有想要学习Vue3的网友,可以大致的浏览一下本文,总体来说本篇博客涵盖了Vue3中绝大部分内容,包含常用的Com ...
- Java 私有接口 【类中嵌套接口】
1.前言 接口十分常用,能规范实现类的命名 和 实现多个实现类的向上转型成统一类型 ,但是接口的修饰符只能是 public吗? 当然不是,可以是private , 难道是像这样? 显然不可以,已经报错 ...
- 转雅虎web前端网站优化 34条军规
雅虎给出了优化网站加载速度的34条法则(包括Yslow规则22条) 详细说明,下载转发 ponytail 的译文 1.Minimize HTTP Requests 减少HTTP请求 图片.css.sc ...
- test_5 排序‘+’、‘-’
题目是:有一组"+"和"-"符号,要求将"+"排到左边,"-"排到右边,写出具体的实现方法. 方法一: l=['-', ...
- func-spring-boot-starter 快速上手
func-spring-boot-starter test 项目地址 func-spring-boot-starter项目地址: https://gitee.com/yiur/func-spring- ...