博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
个性化自己系统的ContextLoaderListener实现
阅读量:6276 次
发布时间:2019-06-22

本文共 9304 字,大约阅读时间需要 31 分钟。

hot3.png

一、问题描述

     WEB项目在继承Spring时候,默认的配置的是ContextLoaderListener

   
contextConfigLocation
   
classpath:spring/spring-context.xml
    
org.springframework.web.context.ContextLoaderListener

这种配置会把Spring-context.xml配置的所有文件都加载进来,当spring-context.xml文件嵌入很多xml文件时候,加载非常的内容非常庞大,特别是涉及到后台定时任务时候,对开发来说非常不方便,还打印一大堆日志,影响开发效率,而且当发布项目的时候,可能在配置文件的修改忘记修改回来,导致发布出现BUG等。

二、问题分析:

      在本地开发的大多时候,是不需要启动一些配置的,例如:quartz的配置,此种情况下,系统可以在配置文件中设置一个开关器,当配置的时候设置值的时候启动,不配置不启动,方便开发,提升效率。

     通过开关器空值加载的spring文件,通过阅读ContextLoader源码发现,Spring在初始化Context的时候,获取到配置文件,只需要对:String initParameter = sc.getInitParameter(CONFIG_LOCATION_PARAM);这个地方修改即可:

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {   if (ObjectUtils.identityToString(wac).equals(wac.getId())) {      // The application context id is still set to its original default value      // -> assign a more useful id based on available information      String idParam = sc.getInitParameter(CONTEXT_ID_PARAM);      if (idParam != null) {         wac.setId(idParam);      }      else {         // Generate default id...         if (sc.getMajorVersion() == 2 && sc.getMinorVersion() < 5) {            // Servlet <= 2.4: resort to name specified in web.xml, if any.            wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +                  ObjectUtils.getDisplayString(sc.getServletContextName()));         }         else {            wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +                  ObjectUtils.getDisplayString(sc.getContextPath()));         }      }   }   wac.setServletContext(sc);   String initParameter = sc.getInitParameter(CONFIG_LOCATION_PARAM);   if (initParameter != null) {      wac.setConfigLocation(initParameter);   }   customizeContext(sc, wac);   wac.refresh();}

        自定义ContextLoaderListener关系如下:

190917_Apih_996569.png

三、解决方案:

1、在web.xml配置文件时候,对配置文件拆分,分多个配置

   
contextConfigLocation
   
      classpath:spring/wms-jdbc.xml,      classpath:spring/wms-job.xml   

2、自定义ContextLoaderListener:

   自定义的ContextLoaderListener,重写configureAndRefreshWebApplicationContext方法,通过配置文件控制获取配置XML的内容:

package com.oneplus.wms.mvc;import com.google.common.base.Joiner;import com.google.common.collect.Lists;import org.apache.commons.lang.ArrayUtils;import org.apache.commons.lang.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.core.io.ClassPathResource;import org.springframework.core.io.support.PropertiesLoaderUtils;import org.springframework.util.ObjectUtils;import org.springframework.web.context.ConfigurableWebApplicationContext;import org.springframework.web.context.ContextLoaderListener;import javax.servlet.ServletContext;import java.io.IOException;import java.util.List;import java.util.Properties;/** * 功能描述:Spring启动时, WMS控制加载Spring配置文件 * * @author: Zhenbin.Li * Date: 16/1/8 Time: 10:45 */public class OneplusContextLoaderListener extends ContextLoaderListener {    /**     * sl4j     */    private static final Logger LOGGER = LoggerFactory.getLogger(OneplusContextLoaderListener.class);    /**     * 配置文件名称     */    private static final String LOADER_CONFIG_FILE = "env-config.properties";    @Override    protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {        if (ObjectUtils.identityToString(wac).equals(wac.getId())) {            // The application context id is still set to its original default value            // -> assign a more useful id based on available information            String idParam = sc.getInitParameter(CONTEXT_ID_PARAM);            if (idParam != null) {                wac.setId(idParam);            } else {                // Generate default id...                if (sc.getMajorVersion() == 2 && sc.getMinorVersion() < 5) {                    // Servlet <= 2.4: resort to name specified in web.xml, if any.                    wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getServletContextName()));                } else {                    wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath()));                }            }        }        wac.setServletContext(sc);        String initParameter = assemblyInitParameter(sc.getInitParameter(CONFIG_LOCATION_PARAM));        if (initParameter != null) {            wac.setConfigLocation(initParameter);        }        customizeContext(sc, wac);        wac.refresh();    }    /**     * WMS对Spring启动设置开关加载配置文件     *     * @param webXmlConfigInitParameter web.xml配置的Spring文件     * @return     */    protected String assemblyInitParameter(String webXmlConfigInitParameter) {        String initParameter = webXmlConfigInitParameter;        ClassPathResource resource = new ClassPathResource(LOADER_CONFIG_FILE);        Properties configureProps;        try {            configureProps = PropertiesLoaderUtils.loadProperties(resource);        } catch (IOException e) {            throw new RuntimeException("加载" + LOADER_CONFIG_FILE + "配置文件失败!", e);        }        Object configJobDebug = configureProps.get(ContextLoaderListenerConfigType.JOB_DEBUG.getType());        if (configJobDebug == null) {            LOGGER.debug("当前未配置加载Spring定时任务启动参数" + ContextLoaderListenerConfigType.JOB_DEBUG.getType() + ", 系统直接启动.");            return initParameter;        }        String jobDebug = String.valueOf(configJobDebug).toUpperCase();        ContextLoaderListenerStatus listenerStatus = ContextLoaderListenerStatus.getByStatus(jobDebug);        if (listenerStatus == null) {            throw new RuntimeException("配置Spring定时任务启动参数" + ContextLoaderListenerConfigType.JOB_DEBUG.getType() + ", ON或者OFF, 当前配置:" + jobDebug);        }        String[] configures = StringUtils.split(initParameter, ",");        if (ArrayUtils.isEmpty(configures)) {            throw new RuntimeException("配置Spring启动文件为空!");        }        LOGGER.debug(LOADER_CONFIG_FILE + "配置" + ContextLoaderListenerConfigType.JOB_DEBUG.getType() + "设置为:" + jobDebug);        // 校验配置文件是否存在        Object jobFileName = configureProps.get(ContextLoaderListenerConfigType.JOB_CONFIG_FILE.getType());        if (jobFileName == null) {            throw new RuntimeException(LOADER_CONFIG_FILE + "配置" + ContextLoaderListenerConfigType.JOB_CONFIG_FILE.getType() + "设置为空!");        }        if (!StringUtils.contains(webXmlConfigInitParameter, String.valueOf(jobFileName))) {            throw new RuntimeException("web.xml无" + jobFileName + "配置信息!");        }        if (StringUtils.equals(jobDebug, ContextLoaderListenerStatus.OFF.getStatus())) {            LOGGER.debug(LOADER_CONFIG_FILE + "配置" + ContextLoaderListenerConfigType.JOB_DEBUG.getType() + "设置为:" + jobDebug + ", WMS不加载配置文件" + jobFileName);            // 获取过滤之后的配置文件            List
 filterConfigs = Lists.newArrayList();            for (String configure : configures) {                if (!StringUtils.contains(configure, String.valueOf(jobFileName))) {                    filterConfigs.add(configure);                }            }            initParameter = Joiner.on(",").join(filterConfigs);        }        return initParameter;    }    /**     * 启动过滤配置文件类型     */    protected enum ContextLoaderListenerConfigType {        JOB_DEBUG("JOB.DEBUG"),        JOB_CONFIG_FILE("JOB.CONFIG.FILE");        private String type;        ContextLoaderListenerConfigType(String type) {            this.type = type;        }        public String getType() {            return type;        }    }    /**     * 开关状态值     */    protected enum ContextLoaderListenerStatus {        ON("ON"),        OFF("OFF");        private String status;        ContextLoaderListenerStatus(String status) {            this.status = status;        }        public String getStatus() {            return status;        }        public static ContextLoaderListenerStatus getByStatus(String statusCode) {            if (StringUtils.isEmpty(statusCode)) {                return null;            }            for (ContextLoaderListenerStatus status : ContextLoaderListenerStatus.values()) {                if (status.getStatus().equals(statusCode)) {                    return status;                }            }            return null;        }    }}

3、配置文件中开关配置:

# 开启定时任务调试,ON:打开,OFF:关闭JOB.DEBUG=OFFJOB.CONFIG.FILE=wms-job.xml

四、系统启动加载结果

  1、设置为OFF

2016-01-12 18:56:25.827 [main] INFO  /-Initializing Spring root WebApplicationContext2016-01-12 18:56:25.869 [main] DEBUG com.oneplus.wms.mvc.OneplusContextLoaderListener-env-config.properties配置JOB.DEBUG设置为:OFF2016-01-12 18:56:25.869 [main] DEBUG com.oneplus.wms.mvc.OneplusContextLoaderListener-env-config.properties配置JOB.DEBUG设置为:OFF, WMS不加载配置文件wms-job.xml

  2、设置为ON

2016-01-12 18:57:22.081 [main] INFO  /-Initializing Spring root WebApplicationContext2016-01-12 18:57:22.125 [main] DEBUG com.oneplus.wms.mvc.OneplusContextLoaderListener-env-config.properties配置JOB.DEBUG设置为:ON...2016-01-12 19:00:00.105 [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-1] DEBUG org.mybatis.spring.SqlSessionUtils-Creating a new SqlSession20

转载于:https://my.oschina.net/198608082556/blog/601526

你可能感兴趣的文章
mac pro 入手,php环境配置总结
查看>>
MyBatis-Plus | 最简单的查询操作教程(Lambda)
查看>>
rpmfusion 的国内大学 NEU 源配置
查看>>
spring jpa 配置详解
查看>>
IOE,为什么去IOE?
查看>>
java 用反射简单应用,将Object简单转换成map
查看>>
Storm中的Worker
查看>>
dangdang.ddframe.job中页面修改表达式后进行检查
查看>>
Web基础架构:负载均衡和LVS
查看>>
Linux下c/c++相对路径动态库的生成与使用
查看>>
SHELL实现跳板机,只允许用户执行少量允许的命令
查看>>
SpringBoot 整合Redis
查看>>
2014上半年大片早知道
查看>>
Android 6.0指纹识别App开发案例
查看>>
正文提取算法
查看>>
轻松学PHP
查看>>
Android android.support.design包
查看>>
CheckBox:屏蔽setChecked方法对OnCheckedChangeListener的影
查看>>
java线程池
查看>>
UI面试内容
查看>>