spring是j2ee比较常用的开源技术,集成spring只需在应用的web.xml文件中进行如下配置:
<!--spring在应用中的全局参数-->
<context-param>
<param-name>contextConfigLocation</param-name>
<!--支持classpath协议,便于多文件的配置-->
<param-value>classpath*:spring/**.spring.xml</param-value>
</context-param>
<!-- 启动spring容器的监听器-->
<listener>
<listenerclass>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
初始化spring/**.spring.xml文件中配置的bean对象、初始化国际化相关的对象(MessageSource)等许多初始化工作就是在ContextLoaderListener中完成,当这些步骤执行完后就是执行刷新上下文事件,详细解析如下:
if (this.context == null) {
this.context = createWebApplicationContext(servletContext);
}
if (this.context instanceof ConfigurableWebApplicationContext) {
configureAndRefreshWebApplicationContext((ConfigurableWebApplicationContext)this.context, servletContext);
}
对于createWebApplicationContext方法:
protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
Class<?> contextClass = determineContextClass(sc);
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
}
ConfigurableWebApplicationContext wac =
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
return wac;
}
所以会走configureAndRefreshWebApplicationContext方法,该方法的结尾就有如下代码:
customizeContext(sc, wac);
wac.refresh();
ConfigurableWebApplicationContext 是一个接口,其抽象实现类是:AbstractApplicationContext类
其中的refresh方法:
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
/**
* Finish the refresh of this context, invoking the LifecycleProcessor's
* onRefresh() method and publishing the
* {@link org.springframework.context.event.ContextRefreshedEvent}.
*/
protected void finishRefresh() {
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
}
发现publishEvent(new ContextRefreshedEvent(this));这行代码就是发布上下文的事件,我们可自己定义一个监听器让其实现ApplicationListener接口,覆盖onApplicationEvent方法,在onApplicationEvent方法中编写想关的业务逻辑:代码如下:
public class custContextListener implements ApplicationListener {
public void onApplicationEvent(ApplicationEvent event) {
if(event instanceof ContextRefreshedEvent) {
}
}
}