1.BeanPostProcessor概述
1.作用:对Spring工厂所创建的对象,进行再加工。它是Spring中的一个很重要的高级特性。AOP的底层实现用到了大量的BeanPostProcessor。
2.BeanPostProcessor是一个接口:只是知道要加工,具体怎样的加工不知道,交给实现者来做。
3.看一下之前Spring工厂是怎么创建对象的:
读配置文件的内容–>反射创建对象–>注入属性—>初始化操作
—>工厂.getBean()获取对象。
4.引入BeanPostProcessor:后置处理时机是在初始化操作前后。
BeanPostProcessor提供了两个方法供我们来实现:
- 1.
postProcessBeforeInitialization
:初始化操作之前的后置处理 - 2.
postProcessAfterInitialization
:初始化操作之后的后置处理 - 3.参数含义:
参数1Object bean
是Spring工厂创建对象;
参数2String beanName
是bean的id值。
5.注意:
- 我们之前学的初始化方法,是写在这个bean类的内部。
- 而后置处理bean,是写在bean类的外部,而且
可以拿到已经创建好的bean独享
,那么岂不是功能很强大,拿到了这个对象,还不是想怎么玩就怎么玩吗? - 实际开发中初始化操作很少做,一般都是靠后置处理Bean来完成BeanPostProcessor即可。既然初始化操作不做,那么上面两个方法实现一个
postProcessAfterInitialization
即可,但是postProcessBeforeInitialization
还要将参数1Object bean
返回出去。
2.BeanPostProcessor开发步骤
注意:无论我们有没有实现BeanPostProcessor接口,重写postProcessAfterInitialization
,postProcessBeforeInitialization
这两个方法,Spring工厂在创建完一个bean对象后都会调用这两个方法。这两个方法在接口中是default
修饰的,有默认的方法体,所以可以执行。而且发现这两个方法没有对拿到bean对象做任何操作,又返回了出去。
1.写一个类实现BeanPostProcessor接口。
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Category category = (Category)bean;
((Category) bean).setName("牛牛牛");
return category;
}
}
2.Spring配置文件进行配置。
<bean id="myBeanPostProcessor" class="com.baizhiedu.basic.beanpost.MyBeanPostProcessor"></bean>
3.原来为name属性注入的是“tttt”,后置处理bean又将name属性赋值为“牛牛牛”。
<bean id="category" class="com.baizhiedu.basic.beanpost.Category">
<property name="name" value="tttt"/>
<property name="id" value="10"/>
</bean>
4.细节注意:
每个bean在Spring工厂创建完之后,都会调用MyBeanPostProcessor
后置处理Bean中的方法。那么我们上面的代码很可能会报强制类型转换的错误:
为什么此处没错,因为我这边工厂读取的是applicationContext2.xml
这个配置文件,这里面除了后置处理Bean只配置了category。所以没有报错
<bean id="category" class="com.baizhiedu.basic.beanpost.Category">
<property name="name" value="tttt"/>
<property name="id" value="10"/>
</bean>
<bean id="myBeanPostProcessor" class="com.baizhiedu.basic.beanpost.MyBeanPostProcessor"></bean>
代码改进:
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof Category){
Category category = (Category)bean;
((Category) bean).setName("牛牛牛");
return category;
}else {
return bean;
}
}
所以每个类如果要进行后置处理的话,要为其单独建一个bean后置处理类