Bean后處理器:
Bean后處理器會在Bean實(shí)例創(chuàng)建成功之后,對Bean實(shí)例進(jìn)行進(jìn)一步的增強(qiáng)處理宰僧。
Bean后處理器必須實(shí)現(xiàn)BeanPOSTProcessor接口,BeanPOSTProcessor接口包含如下兩種方法:
- Object postProcessorBeforeInitialization(Object bean,String name):該方法的第一個參數(shù)是系統(tǒng)即將進(jìn)行后臺處理的Bean實(shí)例观挎,第二個參數(shù)是改Bean的配置Id琴儿。
- Object postProcessorAfterInitialization(Object bean,String name):該方法的第一個參數(shù)是系統(tǒng)即將進(jìn)行后臺處理的Bean實(shí)例,第二個參數(shù)是改Bean的配置Id嘁捷。
當(dāng)Spring容器實(shí)例化Bean實(shí)例之后造成,就會依次調(diào)用Bean后處理器的兩個方法對Bean實(shí)例進(jìn)行增強(qiáng)處理。
MyBeanProcessor.java
package entity;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("Bean后處理器在初始化之后對"+beanName+"進(jìn)行增強(qiáng)處理雄嚣!");
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("Bean后處理器在初始化之前對"+beanName+"進(jìn)行增強(qiáng)處理晒屎!");
//如果該Bean是Chinese類的實(shí)例
if(bean instanceof Chinese)
{
Chinese c=(Chinese)bean;
c.setName("是的");
}
return bean;
}
}
Chinese.java
package entity;
import org.springframework.beans.factory.InitializingBean;
import inter.Axe;
import inter.Persion;
public class Chinese implements Persion,InitializingBean{
private Axe axe;
private String name;
public Chinese()
{
System.out.println("Spring實(shí)例化主調(diào)Bean:Chinese實(shí)例喘蟆。。鼓鲁。");
}
public void setAxe(Axe axe) {
this.axe = axe;
}
public void setName(String name) {
System.out.println("Spring為setName()方法注入依賴關(guān)系蕴轨。。骇吭。");
this.name = name;
}
@Override
public void useAxe() {
// TODO Auto-generated method stub
System.out.println(name+axe.chop());
}
//生命周期方法
public void init()
{
System.out.println("正在執(zhí)行初始化方法init...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("正在執(zhí)行初始化方法afterPropertiesSet");
}
}
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="steelAxe" class="entity.SteelAxe"/>
<bean id="chinese" class="entity.Chinese" init-method="init" p:axe-ref="steelAxe" p:name="依賴注入的值"/>
<!-- 配置Bean后處理器橙弱,可以無需指定id屬性 -->
<bean class="entity.MyBeanProcessor"/>
</beans>
BeanTest.java
package test;
import inter.Persion;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanTest {
public static void main(String[] args)
{
ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
Persion p=ctx.getBean("chinese", Persion.class);
p.useAxe();
}
}
輸出
Bean后處理器在初始化之前對steelAxe進(jìn)行增強(qiáng)處理!
Bean后處理器在初始化之后對steelAxe進(jìn)行增強(qiáng)處理燥狰!
Spring實(shí)例化主調(diào)Bean:Chinese實(shí)例棘脐。。龙致。
Spring為setName()方法注入依賴關(guān)系蛀缝。。净当。
Bean后處理器在初始化之前對chinese進(jìn)行增強(qiáng)處理内斯!
Spring為setName()方法注入依賴關(guān)系蕴潦。像啼。。
正在執(zhí)行初始化方法afterPropertiesSet
正在執(zhí)行初始化方法init...
Bean后處理器在初始化之后對chinese進(jìn)行增強(qiáng)處理潭苞!
是的鋼斧砍柴真快忽冻!
雖然配置文件中指定chinese Bean的name為"依賴注入的值",但這并沒有放生任何作用此疹,該chinese Bean的name成員變量的值被重新設(shè)定為"是的"-----這就是Bean后處理器的作用僧诚。
實(shí)現(xiàn)BeanPostProcessor接口的Bean后處理器可對Bean進(jìn)行任何操作。
Spring提供的兩個常用后處理器:
- BeanNameAutoProxyCreator:根據(jù)Bean實(shí)例的name屬性蝗碎,創(chuàng)建Bean實(shí)例的代理湖笨。
- DefaultAdvisorAutoProxyCreator:根據(jù)提供的Advisor對容器中的所有Bean實(shí)例創(chuàng)建代理。
容器后處理器:
Bean后處理器負(fù)責(zé)處理容器中所有的Bean實(shí)例蹦骑,容器后處理器負(fù)責(zé)處理容器本身慈省。
容器后處理器必須實(shí)現(xiàn)BeanFactoryPostProcessor接口,必須實(shí)現(xiàn)如下一個方法:
- postProcessorBeanFactory(ConfigurableListableBeanFactory beanFactory)
ApplicationContext可自動檢測容器中的容器后處理器眠菇,并且自動注冊容器后處理器边败。但若使用BeanFactory作為容器后處理器,則必須手動調(diào)用該容器后處理器來處理BeanFactory容器捎废。
MyBeanFactoryPostProcessor.java
package entity;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
System.out.println("程序?qū)pring所做的BeanFactory的初始化沒有改變...");
System.out.println("Spring容器是:"+beanFactory);
}
}
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="steelAxe" class="entity.SteelAxe"/>
<bean id="chinese" class="entity.Chinese" init-method="init" p:axe-ref="steelAxe" p:name="依賴注入的值"/>
<!-- 配置Bean后處理器笑窜,可以無需指定id屬性 -->
<bean class="entity.MyBeanProcessor"/>
<!-- 配置容器后處理器 -->
<bean class="entity.MyBeanFactoryPostProcessor"/>
</beans>
BeanTest.java
package test;
import inter.Persion;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanTest {
public static void main(String[] args)
{
ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
Persion p=ctx.getBean("chinese", Persion.class);
p.useAxe();
}
}
輸出
程序?qū)pring所做的BeanFactory的初始化沒有改變...
Spring容器是:org.springframework.beans.factory.support.DefaultListableBeanFactory@29482a89: defining beans [steelAxe,chinese,entity.MyBeanProcessor#0,entity.MyBeanFactoryPostProcessor#0]; root of factory hierarchy
Bean后處理器在初始化之前對steelAxe進(jìn)行增強(qiáng)處理!
Bean后處理器在初始化之后對steelAxe進(jìn)行增強(qiáng)處理登疗!
Spring實(shí)例化主調(diào)Bean:Chinese實(shí)例排截。。。
Spring為setName()方法注入依賴關(guān)系匾寝。搬葬。。
Bean后處理器在初始化之前對chinese進(jìn)行增強(qiáng)處理艳悔!
Spring為setName()方法注入依賴關(guān)系急凰。。猜年。
正在執(zhí)行初始化方法afterPropertiesSet
正在執(zhí)行初始化方法init...
Bean后處理器在初始化之后對chinese進(jìn)行增強(qiáng)處理抡锈!
是的鋼斧砍柴真快!
Spring提供如下幾個常用的容器后處理器:
- PropertyPlaceholderConfigurer:屬性占位符配置器乔外。
- PropertyOverrideConfigurer:重寫占位符配置器床三。
- CustomAutowireConfigurer:自定義自動裝配配置器。
- CustomScopeConfigurer:自定義作用域的配置器杨幼。
Spring沒有提供ApplicationContextPostProcessor撇簿,對于ApplicationContext容器,一樣使用BeanFactoryPostProcessor作為容器后處理器差购。容器后處理器的作用域范圍是容器級四瘫,它只對容器本身進(jìn)行處理,而不對容器中的Bean進(jìn)行處理欲逃。