此文章转载自http://www.blogjava.net/bigbigtooth/archive/2008/03/27/85756.html
用于备忘学习
一、 概述
Spring MVC 的开发是基于 action-servlet.xml 进行配置,但不支持开发模式下进行动态的配置文件载入。本文主要是介绍如何修改 Spring 的源代码,使 Spring 支持动态的配置文件更新,让开发变得更加简单。
二、 实现 action-servlet.xml 动态载入
Spring 提取配置文件的思路 :每次 Spring MVC 会在使用前将 XML 文件载入内存中,并生成映射类的实例,放在 Mapping Map 里。然后判断每个请求,如果有其 URL 所对应的映射,则返回其对应的 Action 实例。
修改思路 :将每次得到请求时,让程序重新载入 xml 文件,并实例化其映射,然后放入 Mapping Map 中。
1、 首先是 FrameworkServlet ,他是 DispatcherServlet 的基类。 XML 在载入内存后,放在一个叫 WebApplicationContext 的类中。找到 getWebApplicationContext() 方法,加入以下代码:
ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils
.instantiateClass(getContextClass());
wac.setParent(WebApplicationContextUtils
.getWebApplicationContext(getServletContext()));
wac.setServletContext(getServletContext());
wac.setNamespace(getNamespace());
if (getContextConfigLocation() != null ) {
wac
.setConfigLocations(StringUtils
.tokenizeToStringArray(
getContextConfigLocation(),
ConfigurableWebApplicationContext. CONFIG_LOCATION_DELIMITERS ));
}
wac.refresh();
this . webApplicationContext = wac;
这样每次再读取 WebApplicationContext 的时候,会重新载入 XML 文件一次。
2、 修改 DispatcherServlet ,这个 Servlet 是处理所有请求的入口。找到 getHandler() 这个方法,他负责找到相应的 Action ,并返回其实例。将代码中的
Iterator it = this.handlerMappings.iterator();
while (it.hasNext()) {
HandlerMapping hm = (HandlerMapping) it.next();
if (logger.isDebugEnabled()) {
logger.debug("Testing handler map [" + hm + "] in DispatcherServlet with name '" +
getServletName() + "'");
}
handler = hm.getHandler(request);
if (handler != null) {
if (cache) {
request.setAttribute(HANDLER_EXECUTION_CHAIN_ATTRIBUTE, handler);
}
return handler;
}
}
改为
initHandlerMappings();
Iterator it = this . handlerMappings .iterator();
while (it.hasNext()) {
BeanNameUrlHandlerMapping hm = (BeanNameUrlHandlerMapping) it.next();
if ( logger .isDebugEnabled()) {
logger .debug( "Testing handler map [" + hm + "] in DispatcherServlet with name '" +
getServletName() + "'" );
}
hm.initApplicationContext();
handler = hm.getHandler(request);
if (handler != null ) {
if (cache) {
request.setAttribute( HANDLER_EXECUTION_CHAIN_ATTRIBUTE , handler);
}
return handler;
}
}
注解:
1) 其中 BeanNameUrlHandlerMapping 是将强制转换 HandlerMapping 时,用子类代替父类,因为子类提供了一个重新初始化的方法 initApplicationContext() ,调用该方法可以重新载入 WebApplicationContext , 并刷新 Mapping Map 。
2) initHandlerMappings() 是 DispatcherServlet 初始化 Mapping 的一个方法。在生成 WebApplicationContext 时,程序还会把放在 ApplicationObjectSupport.applicationContext 保存,因此需要重新初始化一次。
3 、修改 org.springframework.web.servlet.handler.AbstractUrlHandlerMapping
类中的 registerHandler() 方法,它的作用是注册 Mapping ,去掉重复性校验,将下面几行代码注释掉。
if (mappedHandler != null) {
throw new ApplicationContextException(
"Cannot map handler [" + handler + "] to URL path [" + urlPath +
"]: there's already handler [" + mappedHandler + "] mapped");
}
三、实现 applicationContext.xml 的动态载入
Spring 实现思路: applicationContext.xml 是 Spring 默认的配置文件,它利用配置 ContextLoaderListener 的方式,在应用载入时启动,并将 applicationContext.xml 载入内存中,放在 ServletContext 的 Attribute 中,保存的方式是一个 WebApplicationContext 类。当每次调用类时, beanFactory 会调用 WebApplicationContextUtils 中的方法 getWebApplicationContext() ,得到配置信息。
修改方法: 在 ContextLoaderListener 初始化 WebApplicationContext 时,会利用 ContextLoader 提供的方法 initWebApplicationContext() 进行初始化,我们只需要得到 Listener 的这个 ContextLoader 的实例,并重新调用一个初始化的方法就可以实现重新载入了。
修改步骤:
1 、找到 ContextLoaderListener 类的方法 contextInitialized() ,在 Context 初始化的时候将 ContextLoader 的引用放在 ServletContext 的 Attribute 中:
public void contextInitialized(ServletContextEvent event) {
this . contextLoader = createContextLoader();
this . contextLoader .initWebApplicationContext(event.getServletContext());
event.getServletContext().setAttribute( "ListenerContextLoader" , this . contextLoader );
}
注: "ListenerContextLoader" 是自定义的名称,可以任意修改。
3、 找到 WebApplicationContextUtils 类的方法 getWebApplicationContext() ,修改第一行代码:
Object attr = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
改为:
Object attr = null ;
ContextLoader cl = (ContextLoader) sc
.getAttribute( "ListenerContextLoader" );
if (cl != null )
attr = cl.initWebApplicationContext(sc);
这样,在每次获取 WebApplicationContext 时,程序会重新载入 applicationContext.xml 一次。
OK !大功告成, Enjoy your spring developing !!!
分享到:
相关推荐
spring配置文件实例
Spring配置文件集合Spring配置文件集合Spring配置文件集合Spring配置文件集合Spring配置文件集合Spring配置文件集合Spring配置文件集合
本文档是很专业的 Spring动态加载配置文件,实现热部署方案。
spring配置文件spring配置文件spring配置文件spring配置文件spring配置文件spring配置文件spring配置文件spring配置文件spring配置文件spring配置文件spring配置文件spring配置文件spring配置文件spring配置文件...
使用Spring配置文件实现AOP
spring 配置文件 归类 IOC AOPspring 配置文件 归类 IOC AOP
spring配置文件详解,Spring的applicationContext.xml文件代码:
spring 配置 文件
spring配置文件加密实现
Spring配置 Spring 配置 映射 加注释!!!!Spring配置 Spring 配置 映射 加注释!!!!
spring配置文件详解,交你如何理解spring,熟练运用spring
Spring配置文件:注入各种数据时配置文件的配置格式
spring配置文件详细介绍 通过对xml配置的熟练掌握 相信spring真的太简单
文件中进行了详细介绍说明这个配置文件是典型XML格式但是它既冗长又不实用对于需要定义大量 Springbeans大工程来说我们难以阅读和管理它 在这篇文章里对于SpringXML配置我将向你展示12种比较好实战其中些实战不仅...
大型项目的struts,spring配置文件
Spring框架的一个配置文件。Spring框架主要解决了创建对象和管理对象的问题!
官方spring.xml中约束的引用说明文档,配置spring文件的时候添加约束所需要的文档说明.
本word详细介绍了spring各种配置文件,相信对于初学spring的各位大侠是个很好的阶梯、