spring中定时任务的实现可以通过注解@Scheduled来实现,在类上加注解“@EnableScheduling与@Service”
在使用的过程中遇到了两个问题
1、scheduled动态获取报错问题
@Scheduled中的cron可以直接写“0 */1 * * * ?”
也可以使用cron="${cron.job}"
来进行动态的获取定时任务的执行时间。
首先,说第一个问题,在我使用$来动态获取的时候,在编译时会报错cron expression must consist of 6 fields (found 1 in ${cron.job})
这个错误很明显就是把“${cron.job}”当作了一个field,并没有获取到properties中的0 */1 * * * ?
,但是我程序可以正常启动,而且启动后还可以正常的运行(这其中的问题后来我才明白,此处先不说)。为了解决这个问题,我在执行的task上新加了注解@PropertySource(value = "classpath:service.properties")
,service.properties是cron.job存放的文件
以及下面的代码
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
加完上面的代码后,这个问题就解决了
2、scheduled执行时重复执行两次的问题
解决完问题一后,就出现了问题二,scheduled中的代码会重复的执行两次
在我们的web.xml文件中,我们有对spring整合配置,比如配置监听器,上下文加载对象,拦截器,会话的管理等等。
<!--
The Bootstrap listener to start up and shut down Spring's root
WebApplicationContext. It is registered to Servlet Container
-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
上面是我对监听器Listener和上下文对象contextConfigLocation和DispatcherServlet的配置, 出错原因就是没有设置contextConfigLocation为空,导致加载了两次配置文件,所以就有两个操作的上下文的session出现。把上面的代码添加一段即可:
详解可以参考https://blog.csdn.net/pearyangyang/article/details/77248020
然后按照文章中的修改,在web.xml中的servlet中添加下面的代码就可以解决
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
后记,解决完问题二以后,我突然想到问题一,程序构建时候报错,但是依然可以正常运行的问题,是不是因为加载了两次,一次成功一次失败。so,我就把问题一中修改的代码进行还原,果然程序可以正常构建以及运行没有报错。
网友评论