Spring 中提供一些Aware相關接口,像是BeanFactoryAware、 ApplicationContextAware、ResourceLoaderAware、ServletContextAware等等,實做這些 Aware接口的Bean在被初始以後,能夠取得一些相對應的資源,例如實做BeanFactoryAware的Bean在初始後,Spring容器將會 注入BeanFactory的實例,而實做ApplicationContextAware的Bean,在Bean被初始後,將會被注入 ApplicationContext的實例等等。 Bean取得BeanFactory、ApplicationContextAware的實 例目的是什麼,通常的目的就是要取得一些檔案資源的存取、相 關訊息資源或是那些被注入的實例所提供的機制,例如ApplicationContextAware提供了publishEvent()方法,能夠支持基 於Observer模式的事件傳播機制。 ApplicationContextAware接口的定義以下:java
ApplicationContextAware.java public interface ApplicationContextAware { void setApplicationContext(ApplicationContext context); }
咱們這邊示範如何透過實做ApplicationContextAware注入ApplicationContext來實現事件傳播,首先咱們的HelloBean以下:spring
HelloBean.java package onlyfun.caterpillar; import org.springframework.context.*; public class HelloBean implements ApplicationContextAware { private ApplicationContext applicationContext; private String helloWord = "Hello!World!"; public void setApplicationContext(ApplicationContext context) { this.applicationContext = context; } public void setHelloWord(String helloWord) { this.helloWord = helloWord; } public String getHelloWord() { applicationContext.publishEvent( new PropertyGettedEvent("[" + helloWord + "] is getted")); return helloWord; } }
ApplicationContext會由Spring容器注入,publishEvent()方法須要一個繼承ApplicationEvent的對象,咱們的PropertyGettedEvent繼承了ApplicationEvent,以下:app
PropertyGettedEvent.java package onlyfun.caterpillar; import org.springframework.context.*; public class PropertyGettedEvent extends ApplicationEvent { public PropertyGettedEvent(Object source) { super(source); } }
當ApplicationContext執行publishEvent()後,會自動尋找實做ApplicationListener接口的對象並通知其發生對應事件,咱們實做了PropertyGettedListener以下:框架
PrppertyGettedListener.java package onlyfun.caterpillar; import org.springframework.context.*; public class PropertyGettedListener implements ApplicationListener { public void onApplicationEvent(ApplicationEvent event) { System.out.println(event.getSource().toString()); } }
Listener必須被實例化,這咱們能夠在Bean定義檔中加以定義:測試
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="propertyGetterListener" class="onlyfun.caterpillar.PropertyGettedListener"/> <bean id="helloBean" class="onlyfun.caterpillar.HelloBean"> <property name="helloWord"><value>Hello!Justin!</value></property> </bean> </beans>
咱們寫一個測試程序來測測事件傳播的運行:this
Test.java package onlyfun.caterpillar; import org.springframework.context.*; import org.springframework.context.support.*; public class Test { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); HelloBean hello = (HelloBean) context.getBean("helloBean"); System.out.println(hello.getHelloWord()); } }
執行結果會以下所示:code
log4j:WARN No appenders could be found for logger (org.springframework.beans.factory.xml.XmlBeanDefinitionReader). log4j:WARN Please initialize the log4j system properly. org.springframework.context.support.ClassPathXmlApplicationContext: displayName=[org.springframework.context.support.ClassPathXmlApplicationContext; hashCode=33219526]; startup date=[Fri Oct 29 10:56:35 CST 2004]; root of ApplicationContext hierarchy [Hello!Justin!] is getted Hello!Justin!
以上是以實做事件傳播來看看實做Aware接口取得對應對象後,能夠進行的動做,一樣的,您也能夠實做ResourceLoaderAware接口:server
ResourceLoaderAware.java public interface ResourceLoaderAware { void setResourceLoader(ResourceLoader loader); }
實做ResourceLoader的Bean就能夠取得ResourceLoader的實例,如此就能夠使用它的getResource()方法,這對於必須存取檔案資源的Bean至關有用。 基本上,Spring雖然提供了這些Aware相關接口,然而Bean上若實現了這些界面,就算是與Spring發生了依賴,從另外一個角度來看,雖然您能夠直接在Bean上實現這些接口,但您也能夠透過setter來完成依賴注入,例如:xml
HelloBean.java package onlyfun.caterpillar; import org.springframework.context.*; public class HelloBean { private ApplicationContext applicationContext; private String helloWord = "Hello!World!"; public void setApplicationContext(ApplicationContext context) { this.applicationContext = context; } public void setHelloWord(String helloWord) { this.helloWord = helloWord; } public String getHelloWord() { applicationContext.publishEvent(new PropertyGettedEvent("[" + helloWord + "] is getted")); return helloWord; } }
注意此次咱們並無實做ApplicationContextAware,咱們在程序中能夠自行注入ApplicationContext實例:對象
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); HelloBean hello = (HelloBean) context.getBean("helloBean"); hello.setApplicationContext(context); System.out.println(hello.getHelloWord());
就Bean而言,下降了對Spring的依賴,能夠比較容易從現有的框架中脫離。