為了適應目前架構的外掛程式啟動機制(同一平台不同項目載入不同外掛程式和設定檔),不得不想辦法讓外掛程式來選擇性的載入spring設定檔,我是通過重寫spring監聽器來實現載入自訂設定檔。
一、首先,重寫類的主要代碼(主要在中文注釋處):
public class ShineContextLoaderListener extends ContextLoaderListener{private ContextLoader contextLoader;@Overrideprotected 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設定檔和預設的設定檔拼接在一起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,主要就是這樣。