解决 spring quartz 执行两次问题

使用spring quartz的时候出现了一次触发执行两次的问题,上网搜索后发现原因是 ContextLoaderListener 和 DispatcherServlet 对应用上下文重复加载,导致问题出现。

下面是 ContextLoaderListener 中加载的上下文:

<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring/*.xml</param-value>
	</context-param>
	
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>

这是 DispatcherServlet 加载的上下文:

<!-- springMVC配置 -->
	<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring/spring.xml</param-value>
		</init-param>
		<load-on-startup>2</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

经过对比发现,两个上下文都会加载 /WEB-INF/classes/spring/spring.xml, spring.xml 文件则包含了所有的 spring 配置文件,也就是所有的上下文配置。

这样就会产生一个问题,就是  spring.xml 上下文中所有的配置都会被实例化两次,因此也就会导致该问题出现。

 DispatcherServlet 和 ContextLoaderListener 这两个应用上下文之间的关系:

当 DispatcherServlet 启动的时候,它会创建 Spring 上下文,并加载配置文件或者配置类中所声明的 bean。

同时在 Spring Web 应用中,通常还有一个另外的应用上下文,它由 ContextLoaderListener 创建。

两者的分工有所不同, DispatcherServlet 中加载 Web 组件的 bean,如 Controller,viewResolver 以及处理器映射。
而ContextLoaderListener 要加载应用中其他的 bean,这些 bean 通常是驱动应用后端的中间层和数据层组件。

范围而言:DispatcherServlet可以引用由ContextLoaderListener创建的ApplicationContext,反过来却不行,所以解决方案是使用 ContextLoaderListener 加载所有配置,而将 DispatchServlet 上下文去除

<!-- springMVC配置 -->
	<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value></param-value>
		</init-param>
		<load-on-startup>2</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

再次启动工程,问题解决。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值