前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring mvc 启动配置文件加载两遍问题

Spring mvc 启动配置文件加载两遍问题

作者头像
java404
发布2018-05-18 14:26:22
1.6K0
发布2018-05-18 14:26:22
举报
文章被收录于专栏:java 成神之路java 成神之路

问题描述

在使用spring mvc 启动的时候,用到了一个在程序启动时加载的配置方法init-method="initLoad",并启动多线程来做数据同步,但是在程序启动之后发现该方法的任务被执行了两次。后来经过测试发现自己的Spring配置文件被加载了两次。如果是定时任务,那么就会出现两个相同的定时任务,可能对程序的数据造成影响。

下面我们分析下什么情况下可能加载两次配置文件。

情况一:web 项目被tomcat 加载两次

项目名称为:“ade3”

tomcat的/webapps 目录:

项目“ade3”部署在tomcat的webapps目录下

tomcat的server.xml配置文件,配置如下:

如上述配置就会加载两次web项目,所以导致初始化方法执行多次,导致数据不一致的情况。

web项目加载两次原因

tomcat中的server.xml 配置:

  1. 第一次加载:Host 的 appBase=“webapps” 这样Tomcat在启动的时候会把 tomcat/webapps目录下的所有的项目加载并启动。
  2. 第二次加载:Context 的 docBase=“ade3” ,这样tomcat会在查找docBase配置的项目,并加载。

其实相当于tomcat发布了两个项目,两个项目的访问地址为:

  1. http://localhost:8080/ade3 (ade3为webapps目录下的项目名)
  2. http://localhost:8080/ade (ade为 Context的 path="/ade")
解决方法

如果项目部署在tomcat的/webapps 目录下,那么 Context 的 docBase=“”配置为空就可以了。

情况二

  • ContextLoaderListener加载applicationContext.xml 文件
  • DispatcherServer加载 spring-servlet.xml 文件

applicationContext.xml 和 spring-servlet.xml 可能都定义了系统启动加载初始化定时任务的bean。

这样就会在ContextLoaderListener加载applicationContext.xml时启动定时任务 DispatcherServer加载 spring-servlet.xml时也会启动定时任务。相当于加载了两遍bean。

问题分析

问题就出在ContextLoaderListener和DispatcherServlet,他们都可以引入spring,而且每个引入都会实例化一次bean。如果把两个引入方式配置到同一个文件,那么就会导致一个bean被实例化两次。但是,当我们使用Spring Bean的时候,只会用到DispatcherServlet下的Bean,而不会用到ContextLoaderListener下的Bean,这就会导致ContextLoaderListener的bean不会被用到,而且也不会被内存回收到,产生内存泄漏。

解决方法

ContextLoaderListener加载的spring配置文件中的内容不要和DispatcherServer中加载的spring配置文件的内容重叠。

使用ContextLoaderlistener和DispatcherServlet引入Spring的区别
  1. ContextLoaderListener和DispatcherServlet都会生成一个WebApplicationContext(上下文),分别以不同的name存放在容器中。
  2. 同一个容器里,只允许有一个ContextLoaderListener但是可以用多个DispatcherServlet。 DispatcherServlet的context总是ContextLoaderListener的context的子类。
  3. 在获取bean的时候,会先从DispatcherServlet的context获取,如果没有再从ContextLoaderListener的context获取,这就解释了上面的第一点。
  4. 如果两者用的是同一份配置文件,或者他们的定义bean有交叉就会造成部分bean永远不会被用到(泄漏)。
  5. DispatcherServlet还会加载与SpringMVC相关的bean,如RequestMapping...
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.10.15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题描述
  • 情况一:web 项目被tomcat 加载两次
    • web项目加载两次原因
      • 解决方法
      • 情况二
        • 问题分析
          • 解决方法
            • 使用ContextLoaderlistener和DispatcherServlet引入Spring的区别
            相关产品与服务
            容器服务
            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档