为了适应目前框架的插件启动机制(同一平台不同项目加载不同插件和配置文件),不得不想办法让插件来选择性的加载spring配置文件,我是通过重写spring监听器来实现加载自定义配置文件。
一、首先,重写类的主要代码(主要在中文注释处):
public class ShineContextLoaderListener extends ContextLoaderListener{
private ContextLoader contextLoader;
@Override
protected WebApplicationContext createWebApplicationContext(ServletContext sc, ApplicationContext parent) {
// return super.createWebApplicationContext(sc, parent);
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);
// Assign the best possible id value.
if (sc.getMajorVersion() == 2 && sc.getMinorVersion() < 5) {
// Servlet <= 2.4: resort to name specified in web.xml, if any.
String servletContextName = sc.getServletContextName();
wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
ObjectUtils.getDisplayString(servletContextName));
}
else {
// Servlet 2.5's getContextPath available!
try {
String contextPath = (String) ServletContext.class.getMethod("getContextPath").invoke(sc);
wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
ObjectUtils.getDisplayString(contextPath));
}
catch (Exception ex) {
throw new IllegalStateException("Failed to invoke Servlet 2.5 getContextPath method", ex);
}
}
//将默认的spring配置文件与插件注入的配置文件融合
String configLocation = sc.getInitParameter(CONFIG_LOCATION_PARAM); //这里获取到web.xml中通过param配置的spring配置文件路径
String fusionConfigLocation = ConfigFactory.getFactory().fusionSpringXml(configLocation, "Spring"); //将动态加载的spring配置文件和默认的配置文件拼接在一起
/* 这里拼出结果类似:classpath:com/shine/docs/config/dbSpring.xml,classpath:com/shine/jbpm/config/jbpmSpring.xml */
wac.setParent(parent);
wac.setServletContext(sc);
wac.setConfigLocation(fusionConfigLocation); //设置配置文件路径为拼接后的值
customizeContext(sc, wac);
wac.refresh();
return wac;
}
/**
* Initialize the root web application context.
*/
public void contextInitialized(ServletContextEvent event) {
//初始化系统配置,将启动时需要的配置文件加载到系统全局变量中
ConfigFactory.getFactory().init(event.getServletContext());
this.contextLoader = createContextLoader();
if (this.contextLoader == null) {
this.contextLoader = this;
}
this.contextLoader.initWebApplicationContext(event.getServletContext());
}
}
二、将web.xml中的配置的spring监听器改成重写后的类
<!--
Spring监听器,原class:org.springframework.web.context.ContextLoaderListener
contextConfigLocation值已改成通过插件加载,在此处保留的话不要与插件中加载的冲突
如果同时使用SpringMvc则注意不要重复加载
-->
<listener>
<listener-class>com.shine.spring.ShineContextLoaderListener</listener-class>
</listener>
<!--
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
-->
OK,主要就是这样。