2、Application Context
(1)什么是Application Context
l 聚集能够被所有组件使用的应用程序信息
l Bean定义的位置
l 加载多个contexts
l 层次contexts
l il8n,消息资源
l 资源访问
l 事件传播
(2)ApplicationContext
l 扩展BeanFactory
l 可以有一个父context
l 实现:
? FileSystemXmlApplicationContext
? ClassPathXmlApplicationContext
? XmlWebApplicationContext
l 例子:
ApplicationContext ctx = new FileSystemXmlApplicationContext("c:/beans.xml");
ExampleBean eb = (ExampleBean)ctx.getBean("exampleBean");
l ApplicationContext可以读取多个文件
String[] ctxs = new String[]{"ctx1.xml", "ctx2.xml"};
ApplicationContext ctx = new FileSystemXmlApplicationContext(ctxs);
(3)层次contexts
l 如果一个Bean在context中没有找到,就会到父context中去找
l 创建一个层次contexts
ApplicationContext parent = new ClassPathXmlApplicationContext("ctx1.xml");
ApplicationContext ctx = new FileSystemXmlApplicationContext("ctx2.xml", parent);
(4)资源
l ApplicationContext处理资源位置
l ApplicationContext方法:
Resource getResource(String location)
? URL全路经,如file:c:/test.dat
? 相对文件路径,如WEB-INF/test.dat
? classpath伪URL,如classpath:test.dat
interface Resource {
boolean exists();
boolean isOpen();
String getDescription();
File getFile() throws IOException;
InputStream getInputStream() throws IOException;
}
(5)资源编辑器
l 内建PropertyEditor
l 能够在Bean定义中配置资源属性
l 例子:
<property name="resourceProperty">
<value>example/image.gif</value>
</property>
(6)il8n
l 国际化应用程序消息
l ApplicationContext方法:
String getMessage(String code, Object[] args, String default, Locale loc)
代表一个messageSource Bean。
l ApplicationContext搜索messageSource Bean(必须实现MessageSource接口)
l 例子:在classpath中定义两个资源束messages和errors
<bean id="messageSource" class="...ResourceBundleMessageSource">
<property name="basenames">
<value>messages,errors</value>
</property>
</bean>
在classpath中搜索:
messages_pt_BR.properties errors_pt_BR.properties
messages_pt.properties errors_pt.properties
messages.properties errors.properties
(7)事件
l 事件传播
? ApplicationContext处理事件,调用侦听器
? Beans必须实现ApplicationListener接口来接收事件
? 应用程序可以扩展ApplicationEvent
? 内建事件:
2 ContextRefreshedEvent
2 ContextClosedEvent
2 RequestHandledEvent
l 侦听事件
public class MyListenerBean implements ApplicationListener {
public void onApplicationEvent(ApplicationEvent e) {
// process event
}
}
l 发送事件
public class ExampleBean implements ApplicationContextAware {
ApplicationContext ctx;
public void setApplicationContext(ApplicationContext ctx)
throws BeansException {
this.ctx = ctx;
}
public void sendEvent() {
ctx.publishEvent(new MyApplicationEvent(this));
}
}
(8)BeanFactoryPostProcessor
l 可以用来在它内部配置BeanFactory或Beans;应用程序contexts在它们的Bean定义中自动检测BeanFactoryPostProcessor的Beans,在其它Beans创建之前应用它们
l post processor bean必须实现BeanFactoryPostProcessor接口
l 例子:增加定制编辑器到context中
public class MyPostProcessor implements BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory bf) {
DateFormat fmt = new SimpleDateFormat("d/M/yyyy");
CustomDateEditor dateEditor = new CustomDateEditor(fmt, false);
bf.registerCustomEditor(java.util.Date.class, dateEditor);
}
}
<bean id="myPostProcessor" class="eg.MyPostProcessor"/>
(9)CustomEditorConfigurer
l BeanFactoryPostProcessor实现允许方便的注册定制属性编辑器
<bean id="customEditorConfigurer" class="...CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date">
<bean class="...CustomDateEditor">
<constructor-arg index="0">
<bean class="java.text.SimpleDateFormat">
<constructor-arg><value>d/M/yyyy</value></constructor-arg>
</bean>
</constructor-arg>
<constructor-arg index="1"><value>false</value></constructor-arg>
</bean>
</entry>
</map>
</property>
</bean>
(10)典型的应用程序contexts
l 应用程序contexts通常与J2EE服务器定义的一个范围相联系
? Web应用程序(javax.servlet.ServletContext):Sring提供通过侦听器或Servlet实例化该context的能力
? Servlet:每个Servlet能够拥有自己的应用程序context,来源于Web应用程序context
? EJBs:从EJB jar文件中的XML文档中加载
l 不需要使用Singleton来引导Bean Factory