Spring中提供一些Aware相关接口,像是BeanFactoryAware、 ApplicationContextAware、ResourceLoaderAware、ServletContextAware等等,实作这些 Aware接口的Bean在被初始之后,可以取得一些相对应的资源,例如实作BeanFactoryAware的Bean在初始后,Spring容器将会注入BeanFactory的实例,而实作ApplicationContextAware的Bean,在Bean被初始后,将会被注入 ApplicationContext的实例等等。
Bean取得BeanFactory、ApplicationContextAware的实例目的是什么,一般的目的就是要取得一些档案资源的存取、相 关讯息资源或是那些被注入的实例所提供的机制,例如ApplicationContextAware提供了publishEvent()方法,可以支持基于Observer模式的事件传播机制。
ApplicationContextAware接口的定义如下:
- public interface ApplicationContextAware {
- void setApplicationContext(ApplicationContext context);
- }
public interface ApplicationContextAware { void setApplicationContext(ApplicationContext context); }
我们这边示范如何透过实作ApplicationContextAware注入ApplicationContext来实现事件传播,首先我们的HelloBean如下:
- 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;
- }
- }
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,如下:
- import org.springframework.context.*;
- public class PropertyGettedEvent extends ApplicationEvent {
- public PropertyGettedEvent(Object source) {
- super(source);
- }
- }
import org.springframework.context.*; public class PropertyGettedEvent extends ApplicationEvent { public PropertyGettedEvent(Object source) { super(source); } }
当ApplicationContext执行publishEvent()后,会自动寻找实作ApplicationListener接口的对象并通知其发生对应事件,我们实作了PropertyGettedListener如下:
- import org.springframework.context.*;
- public class PropertyGettedListener implements ApplicationListener {
- public void onApplicationEvent(ApplicationEvent event) {
- System.out.println(event.getSource().toString());
- }
- }
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="cn.edu.ccnu.inc.HelloBean">
- <property name="helloWord"><value>Hello!Justin!</value></property>
- </bean>
- </beans>