BeanPostProcessor
Spring提供的扩展接口,我们常称为后置处理器,作用是在Bean对象在实例化和依赖注入完毕后,在调用初始化方法的前后添加我们自己的逻辑。
注意:是Bean实例化完毕后及依赖注入完成后触发的。
接口的源码如下:
public interface BeanPostProcessor {
/** 实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/** 实例化、依赖注入、初始化完毕时执行 */
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
- InstantiationAwareBeanPostProcessor
实例化bean后置处理器,bean实例化前后做一些事情。注意,是先实例化才到初始化的! - SmartInstantiationAwareBeanPostProcessor
智能实例化bean后置处理器,就是比InstantiationAwareBeanPostProcessor多三个接口,能做更多处理。 - DestructionAwareBeanPostProcessor
销毁bean后置处理器,就是销毁bean之前可以增加一些处理。 - MergedBeanDefinitionPostProcessor
合并bean定义后置处理器。
1、自定义的后置处理器
package com.qgbihc.spring;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化 before--实例化的bean对象:" + bean + "\t" + beanName);
//bean初始化之前,要干点什么,但是干不干都要把人家给返回回去,不能一进来就出不去了~
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化 after...实例化的bean对象:" + bean + "\t" + beanName);
//bean已经初始化完了,这时候你想干点什么或者什么都不干,和上面一样,都要给人家返回回去
return bean;
}
}
2、Bean对象
package com.qgbihc.spring;
public class MyBean {
private int id;
private String name;
public MyBean() {
System.out.println("构造函数");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("设置" + name);
this.name = name;
}
private void init() {
System.out.println("自定义的初始化方法");
}
}
3、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 class="com.qgbihc.spring.MyBean" id="myBean" init-method="init">
<property name="name" value="姓名" />
</bean>
<!-- 注册处理器 -->
<bean class="com.qgbihc.spring.MyBeanPostProcessor"></bean>
</beans>
4、测试代码
@Test
public void testBeanPostProcessor() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext-MyBeanPostProcessor.xml");
MyBean bean = ac.getBean(MyBean.class);
System.out.println(bean);
}
输出结果
构造函数
设置姓名
初始化 before--实例化的bean对象:com.qgbihc.spring.MyBean@6a01e23 myBean
自定义的初始化方法
初始化 after...实例化的bean对象:com.qgbihc.spring.MyBean@6a01e23 myBean
com.qgbihc.spring.MyBean@6a01e23
通过输出语句我们能看到postProcessBeforeInitialization方法的输出语句是在Bean实例化及属性注入后执行的,且在自定义的初始化方法之前执行(通过init-method指定)。
而postProcessAfterInitialization方法是在自定义初始化方法执行之后执行的。
BeanPostProcessor的使用
解决同一个接口有多个实现类,自动注入冲突的问题。
核心思想:不使用Autowired注解,使用自定义注解。在自定义BeanPostProcessor中,根据自定义注解拦截要注入的接口实现类,运用java反射和代理的来进行有效的实现类注入。