spring的bean周期中BeanPostProcessor浅析
参考:https://www.cnblogs.com/sishang/p/6576665.html
https://www.jianshu.com/p/890446a3d477
1. 基本概念
spring容器在实例化bean之后(通过构造器创建对象并注入属性值即为实例化),可以使用BeanPostProcessor接口在bean的初始化方法前后根据需要做自己的逻辑处理。
2. BeanPostProcessor后置处理器的使用
BeanPostProcessor接口有两个方法,postProcessBeforeInitialization和postProcessAfterInitialization,默认情况下后置处理器会处理容器中所有的bean。
postProcessBeforeInitialization在bean初始化方法之前调用,初始化方法包括:bean标签添加init-method属性指定Java类中初始化方法、 @PostConstruct注解指定初始化方法,Java类实现InitailztingBean接口所产生的afterPropertiesSet()方法等。
postProcessAfterInitialization在bean初始化方法之后调用。
public class PostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean,
String beanName) throws BeansException {
if ("narCodeService".equals(beanName)) {//此方法获取容器中所有的bean,根据 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;
}
}
上段代码两个方法的第一个参数为bean对象,第二个参数为bean对象的全称名称(包名加类名)。然后该实现类配置在spring配置文件中就可以使用了。多个后置处理器按照配置顺序执行,可以配置order属性进行设置优先级。
然后将PostProcessor注入到spring容器中,比如配置到application.xml文件中。
下面有个完成实例:
package renchaofeng;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class PostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if("messageService".equals(beanName)) {
System.out.println("messageService init method after..");
}
if("testnreImpl".equals(beanName)) {
System.out.println("testnreImpl init method after..");
}
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if("messageService".equals(beanName)) {
System.out.println("messageService init method before..");
}
if("testnreImpl".equals(beanName)) {
System.out.println("testnreImpl init method before..");
}
return bean;
}
}
将 PostProcessor配置到spring容器中,
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName">
<bean id="postProcessor" class="renchaofeng.PostProcessor"/>
</beans>
分别定义两个接口和其实现类:
package renchaofeng;
public interface MessageService {
String getMessage();
}
package renchaofeng;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MessageServiceImpl implements MessageService,InitializingBean {
public String getMessage() {
return "hello world";
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("message init method...");
}
}
package renchaofeng;
public interface Testnre {
void getRen();
}
package renchaofeng;
import org.springframework.beans.factory.InitializingBean;
public class TestnreImpl implements Testnre,InitializingBean {
@Override
public void getRen() {
System.out.println("fffff..");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("TestnreImpl init method..");
}
}
然后把上面两个实现类配置到spring容器中:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName">
<bean id="messageService" class="renchaofeng.MessageServiceImpl"/>
<bean id="postProcessor" class="renchaofeng.PostProcessor"/>
<bean id="testnreImpl" class="renchaofeng.TestnreImpl"/>
</beans>
写个测试类如下:
package renchaofeng;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpring {
public static void main(String[] args) throws BeansException{
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/application-ren.xml");
System.out.println("context 启动成功");
MessageService messageService = (MessageService)context.getBean("messageService");
System.out.println(messageService.getMessage());
}
}
运行结果如下:
messageService init method before..
message init method…
messageService init method after..
testnreImpl init method before..
TestnreImpl init method..
testnreImpl init method after..
context 启动成功
hello world
说明每当一个bean执行初始化方法时,都会调用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法。
还没有评论,来说两句吧...