spring提供了很多扩展接口,其中就包括有BeanPostProcessor,其作用是——当我们在Spring容器中完成bean的实例化、配置以及其他初始化方法前后要添加一些自己的事务处理逻辑时,我们需要定义一个或者多个BeanPosrtProcessor接口实现类,然后注册到Spring容器中。
首先,BeanPostProcessor的说明如下:
public interface BeanPostProcessor {
/**
* Apply this BeanPostProcessor to the given new bean instance before 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 after 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;
}
可以看出,对bean初始化的加工逻辑很简单,只需要定义一个
BeanPostProcessor的实现类,如果我们需要在bean的实例化前添加事务逻辑,则需要在postProcessBeforeInitialization()方法中写逻辑操作,如果我们需要在bean的实例化完成后添加事务逻辑,则需要在postProcessAfterInitialization()方法中写逻辑操作。
具体例子如下:
UserService层代码:
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
// TODO Auto-generated method stub
System.out.println("添加用户");
}
@Override
public User queryUserByXX() {
// TODO Auto-generated method stub
System.out.println("查找用户");
return null;
}
@Override
public void update() {
System.out.println("更新用户");
// TODO Auto-generated method stub
}
@Override
public void delete() {
System.out.println("删除用户");
// TODO Auto-generated method stub
}
}
MyBeanPostProcessor实现BeanPostProcessor接口,实现对bean实例化的加工
public class MyBeanPostProcessor implements BeanPostProcessor{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("bean初始化前"+beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("bean初始化后"+beanName);
return bean;
}
}
注意:
MyBeanPostProcessor中的两个方法返回值都不能是null,如果返回null,那么在后续初始化方法中将会报空指针异常或者通过getBean()方法获取不到实例化对象,因为实例化的对象没有放回到SpringIOC容器中。
XML配置文件:
测试代码:
public class PostTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
UserServiceImpl userService = (UserServiceImpl) context.getBean("userServiceImpl");
userService.queryUserByXX();
}
测试结果:
结果显示说明我们在调用bean之前,bean已经实现了初始化前和初始后的逻辑。
那么,如何实现调用多个BeanPostProcessor,具体例子如下:
首先,实现类应该同时实现BeanPostProcessor和Ordered,实现Ordered接口的getOrder方法,该方法返回一整数,返回值越小,优先级越高,默认为0;
如果不实现Ordered接口,则按照applicationContext.xml(spring配置文件)中声明的先后顺序执行
实现类MyBeanPostProcessor代码:
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
public class MyBeanPostProcessor implements BeanPostProcessor,Ordered{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("bean初始化前"+beanName+"0");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("bean初始化后"+beanName+"0");
return bean;
}
@Override
public int getOrder() {
// TODO Auto-generated method stub
return 0;
}
}
实现类MyBeanPostProcessor2代码:
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
public class MyBeanPostProcessor2 implements BeanPostProcessor,Ordered{
@Override
public int getOrder() {
// TODO Auto-generated method stub
return 1;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化方法前"+beanName+"1");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("初始化方法后"+beanName+"1");
return bean;
}
}
XML配置文件:
其余代码相同,不再显示,测试结果如下:
有结果可见,bean的实例化加工顺序按设定的优先级执行