Spring容器被被多次初始化问题排查解决方案

2 篇文章 0 订阅
1 篇文章 0 订阅

问题描述
    项目中使用quartz创建了一个定时任务,在系统启动后立即执行,我发现项目在启动过程中,会执行4次这个定时任务,也就是说项目被初始化了4次,这样会导致与任务相关的点出问题
    最初我是现从精简Spring与SpringMVC的配置开始入手解决这个问题的,精简完成后由初始化4次降为了两次,后来又通过配置tomcat将初始化两次降为一次,至此解决了这个问题,下面就来详细讲一下这两步!
第一步:精简配置项
  项目本身Spring与SpringMVC的配置文件是写在一起的, 在web.xml中配置为

	<!-- 
		加载Spring应用上下文
		ContextLoaderListener加载应用中的bean,这些bean通常是驱动应用程序后端的中间层和数据层组件
	 -->
	<listener>
		<!-- Servlet监听器 -->
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
  	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			classpath*:/spring/applicationContext.xml
		</param-value>
	</context-param>

	<!-- 
		创建SpringMVC应用上下文
		DispatcherServlet加载包含Web组件的bean,如控制器、视图解析器以及处理器映射
	-->
	<servlet>
		<servlet-name>SpringMVC</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- 指定SpringMVC配置文件加载地址 -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:/spring/applicationContext.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
		<!-- <async-supported>true</async-supported> -->
	</servlet>
	<servlet-mapping>
		<servlet-name>SpringMVC</servlet-name>
		<url-pattern>*.shtml</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/dwr/*</url-pattern>
    </servlet-mapping>

   这样会有一个问题,会导致applicationContext.xml中配置的bean和被扫描到的注解类,都会被ContextLoaderListener与DispatcherServlet重复加载,这里是第一个问题点。
   随后我将配置文件拆分为两个,applicationContext.xml与applicationContext-mvc.xml,我希望ContextLoaderListener与DispatcherServlet加载各自的上下文
第二步:配置tomcat
   在tomcat中配置的Host与其子元素Context元素中的两个属性
的冲突配置会导致了应用程序重复加载

      <!-- 
      		Host代表虚拟主机,在同一个Engine中可以有多个Host,
      		Host元素主要属性
      			appBase : 指定虚拟主机的目录,可以指定绝对路径,也可以指定CATALINA_HOME的相对目录,
      				没有设置默认值为CATALINA_HOME/webapps
      			autoDeploy : 如果此项设置为true,标识当Tomcat服务器处于运行阶段,能够检测appBase下的文件,
      				如果有新的Web应用加入进来,则会自动发布这个Web应用
      			name : 指定虚拟主机的名称
      			unpackWARs :如果此项设为true,则表示把appBase属性指定目录下的web应用的WAR文件先展开为开放结构后再运行,
      				如果设为false,则直接运行WAR文件
       -->
      <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
           <!-- 
			Context 元素代表了运行在虚拟主机<Host> 上的单个Web应用
			在Host中可以有多个Context元素
			主要属性:
				path : 指定访问该应用程序的URL入口
				docBase : 指定Web应用程序的文件路径,可以给定绝对路径,也可以给定相对于<Host>的appBase属性的相对路径
					如果Web应用采用开放目录机构,则指定Web应用的根目录;如果Web应用是个WAR文件,则指定WAR的文件路径
				reloadable : 属性默认为false,如果为true的话,Tomcat服务器会在运行状态下监视 WEB-INF/classes 和 WEB-INF/lib目录下的classes文件的改动,以及监视
						web应用的WEB-INF/web.xml文件的改动,如果检测到以上文件被改动,则服务器会自动重新加载WEB应用。在web应用开发调试阶段,把reloadable设为
						true,可以方便对web应用程序的调试,在web应用正式发布阶段,把reloadable设为false,可以降低tomcat的运行负荷
						提高tomcat的运行性能
				className : 
			标准Context组件的专有属性
				cachingAllowed :
				cacheMaxSize : 
				workDir : 
				uppackWar : 
		 -->
      	<Context docBase="pl" path="/pl" reloadable="true" source="org.eclipse.jst.jee.server:pl_web_20180807"/>
      </Host>

   在Tomcat加载时会将Host元素的appbase属性配置的路径下所有应用程序启动,然后再启动Context元素的docBase属性配置的路径下的应用程序。
   如果你Context元素的docBase属性配置的路径下的应用程序,同在Host元素的appbase属性配置的路径下,那么就会被启动两次,这是第二个问题点。
   我是因为两个路径配置重叠了所以导致了启动了两次,所以我将Context元素docBase置为了空

完结

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值