Bean后處理器:
Bean后處理器會在Bean實例創建成功之后,對Bean實例進行進一步的增強處理。
Bean后處理器必須實現BeanPOSTProcessor接口,BeanPOSTProcessor接口包含如下兩種方法:
- Object postProcessorBeforeInitialization(Object bean,String name):該方法的第一個參數是系統即將進行后臺處理的Bean實例,第二個參數是改Bean的配置Id。
- Object postProcessorAfterInitialization(Object bean,String name):該方法的第一個參數是系統即將進行后臺處理的Bean實例,第二個參數是改Bean的配置Id。
當Spring容器實例化Bean實例之后,就會依次調用Bean后處理器的兩個方法對Bean實例進行增強處理。
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+"進行增強處理!");
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("Bean后處理器在初始化之前對"+beanName+"進行增強處理!");
//如果該Bean是Chinese類的實例
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實例化主調Bean:Chinese實例。。。");
}
public void setAxe(Axe axe) {
this.axe = axe;
}
public void setName(String name) {
System.out.println("Spring為setName()方法注入依賴關系。。。");
this.name = name;
}
@Override
public void useAxe() {
// TODO Auto-generated method stub
System.out.println(name+axe.chop());
}
//生命周期方法
public void init()
{
System.out.println("正在執行初始化方法init...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("正在執行初始化方法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進行增強處理!
Bean后處理器在初始化之后對steelAxe進行增強處理!
Spring實例化主調Bean:Chinese實例。。。
Spring為setName()方法注入依賴關系。。。
Bean后處理器在初始化之前對chinese進行增強處理!
Spring為setName()方法注入依賴關系。。。
正在執行初始化方法afterPropertiesSet
正在執行初始化方法init...
Bean后處理器在初始化之后對chinese進行增強處理!
是的鋼斧砍柴真快!
雖然配置文件中指定chinese Bean的name為"依賴注入的值",但這并沒有放生任何作用,該chinese Bean的name成員變量的值被重新設定為"是的"-----這就是Bean后處理器的作用。
實現BeanPostProcessor接口的Bean后處理器可對Bean進行任何操作。
Spring提供的兩個常用后處理器:
- BeanNameAutoProxyCreator:根據Bean實例的name屬性,創建Bean實例的代理。
- DefaultAdvisorAutoProxyCreator:根據提供的Advisor對容器中的所有Bean實例創建代理。
容器后處理器:
Bean后處理器負責處理容器中所有的Bean實例,容器后處理器負責處理容器本身。
容器后處理器必須實現BeanFactoryPostProcessor接口,必須實現如下一個方法:
- postProcessorBeanFactory(ConfigurableListableBeanFactory beanFactory)
ApplicationContext可自動檢測容器中的容器后處理器,并且自動注冊容器后處理器。但若使用BeanFactory作為容器后處理器,則必須手動調用該容器后處理器來處理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("程序對Spring所做的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();
}
}
輸出
程序對Spring所做的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進行增強處理!
Bean后處理器在初始化之后對steelAxe進行增強處理!
Spring實例化主調Bean:Chinese實例。。。
Spring為setName()方法注入依賴關系。。。
Bean后處理器在初始化之前對chinese進行增強處理!
Spring為setName()方法注入依賴關系。。。
正在執行初始化方法afterPropertiesSet
正在執行初始化方法init...
Bean后處理器在初始化之后對chinese進行增強處理!
是的鋼斧砍柴真快!
Spring提供如下幾個常用的容器后處理器:
- PropertyPlaceholderConfigurer:屬性占位符配置器。
- PropertyOverrideConfigurer:重寫占位符配置器。
- CustomAutowireConfigurer:自定義自動裝配配置器。
- CustomScopeConfigurer:自定義作用域的配置器。
Spring沒有提供ApplicationContextPostProcessor,對于ApplicationContext容器,一樣使用BeanFactoryPostProcessor作為容器后處理器。容器后處理器的作用域范圍是容器級,它只對容器本身進行處理,而不對容器中的Bean進行處理。