SpringMVC Cron定时器Demo常见问题解决方案

该技术的不适用的场景

如果在集群环境下,多台服务器中只希望有一台执行,那 Spring 自带的这种定时器方式可能不太符合你的需要。
但是,如果每台服务器都需要独立执行该定时器任务,且相互之间不存在同步,那么还是可以考虑的

SpringMVC 定时器

本文着重介绍的是 SpringMVC 配置定时器的方式,而不是 SpringBoot 配置定时器的方式。

注解方式

首先,在 Clock 类上添加 @Component,然后,在需要定时执行的方法上面加上 @Scheduled,最后指定 cron 表达式。

项目结构:

Clock.java

package coderead.spring.scheduled;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class Clock {
  // 每5秒钟执行一次
  @Scheduled(cron = "*/5 * * * * ?")
  public void testTime() {
    System.out.println(new Date());
  }
}

spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:task="http://www.springframework.org/schema/task"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/task
      http://www.springframework.org/schema/task/spring-task.xsd">

  <mvc:annotation-driven />

  <context:component-scan base-package="coderead.spring.*" />

  <!-- 定时任务支持注解 -->
  <task:annotation-driven />
</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
     version="3.1">
  <!--配置多个上下文会导致多次执行-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/spring-mvc.xml</param-value>
  </context-param>

  <!-- ================================== listener ================================== -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- ================================== servlet ================================== -->
  <!-- 前端控制器 -->
  <servlet>
    <servlet-name>dispatcherServlet</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>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>coderead.spring</groupId>
  <artifactId>spring-scheduled-test</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <properties>
    <spring.version>5.1.6.RELEASE</spring.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>9.4.33.v20201020</version>
      </plugin>
    </plugins>
  </build>

</project>

如果你不知道怎么用 jetty 启动项目,你可以考虑参考 使用maven-Jetty9-plugin插件运行第一个Servlet

xml 配置方式

如果你需要使用 xml 配置,你会发现 @Scheduled 注解和 <task:scheduled> 有着相同的属性。因此我们将上一节的代码稍稍改动一下:

Clock.java 去掉注解

package coderead.spring.scheduled;
import java.util.Date;
public class Clock {
  public void testTime() {
    System.out.println(new Date());
  }
}

spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:task="http://www.springframework.org/schema/task"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/task
      http://www.springframework.org/schema/task/spring-task.xsd">

  <mvc:annotation-driven />

  <context:component-scan base-package="coderead.spring.*" />

  <!--用 xml 方式注入 Clock Bean-->
  <bean id="clock" class="coderead.spring.scheduled.Clock" />
  <!--用 xml 方式设置定时器-->
  <task:scheduled-tasks>
    <task:scheduled ref="clock" method="testTime" cron="*/5 * * * * ?"/>
  </task:scheduled-tasks>

</beans>

常见问题

@Scheduled 定时任务不生效

@Scheduled定时任务不生效???

  • 此方法不能有参数
  • 此方法不能有返回值
  • 此类中不能包含其他带任何注解的方法(发现新大陆)

还有一种可能就是没有在 spring-mvc.xml 文件中加入 <task:annotation-driven /> 而不仅仅是加入 <mvc:annotation-driven />

@Scheduled 定时任务执行两次

@Scheduled Spring定时任务每次执行两次解决方案

主要原因是 web.xml 同时设置了 <context-param> 和 <init-param> 都设置了 contextConfigLocation,两次加载配置文件

<web-app ....>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/spring-mvc.xml</param-value>
  </context-param>
  ...
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring/spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  ...
</web-app>

cron 表达式

cron 表达式是用来规定代码执行周期的一种表达式,cron表达式详解 这篇文章详细的讲解了 cron 表达式的使用细节。
以我的浅陋的经验,我对 cron 表达式的记忆是:

常用的 cron 表达式由 6 个域组成,域和域之间以空格分开

域从左到右,时间单位从秒开始逐步增大。他们分别是 "秒 分 时 日期 月份 星期"

因为日期和星期会相互影响,通常如果其中一个用 非? 表示任意,则另一个必须用 ? 表示“任意”。

原因:通常,在指定日期条件之后,我们虽然希望“任意星期几”,但是实际上,此时星期需要根据日期的变化而相应变化,做不到完全任意。

你还可以通过 在线 Cron 表达式 来帮助你理解前人代码中的 cron 表达式的含义,或者根据你的需求生成一个新的 cron 表达式。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Springboot定时任务Scheduled重复执行操作

    今天用scheduled写定时任务的时候发现定时任务一秒重复执行一次,而我的cron表达式为 * 0/2 * * * * . 在源码调试的过程中,发现是我的定时任务执行过程太短导致的. 于是我另外写了个简单的定时任务 @Component public class TestJob { @Scheduled(cron = "* 0/2 * * * *") public void test() { System.out.println("测试开始"); System.o

  • Spring Task定时任务每天零点执行一次的操作

    最近根据项目的需求,需要限制用户每天的发送短信数量.这样以来就需要写一个定时任务,每天去置零一次所有用户的发送短信统计数量. 首先,在application.xml文件中添加 <task:annotation-driven /> 接着就是编写自己的业务处理逻辑 package com.*.*.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.sch

  • Spring @Scheduler使用cron表达式时的执行问题详解

    前言 Spring Scheduler里有两个概念:任务(Task)和运行任务的框架(TaskExecutor/TaskScheduler).TaskExecutor顾名思义,是任务的执行器,允许我们异步执行多个任务.TaskScheduler是任务调度器,来运行未来的定时任务.触发器Trigger可以决定定时任务是否该运行了,最常用的触发器是CronTrigger.Spring内置了多种类型的TaskExecutor和TaskScheduler,方便用户根据不同业务场景选择. 本文主要介绍了关

  • Spring Boot支持Crontab任务改造的方法

    在以往的 Tomcat 项目中,一直习惯用 Ant 打包,使用 build.xml 配置,通过 ant -buildfile 的方式在机器上执行定时任务.虽然 Spring 本身支持定时任务,但都是服务一直运行时支持.其实在项目中,大多数定时任务,还是借助 Linux Crontab 来支持,需要时运行即可,不需要一直占用机器资源.但 Spring Boot 项目或者普通的 jar 项目,就没这么方便了. Spring Boot 提供了类似 CommandLineRunner 的方式,很好的执行

  • springboot实现多实例crontab抢占定时任务(实例代码)

    github: https://github.com/jiasion/eslog wechat:minghui-666 利用redisson实现多实例抢占定时任务 pom.xml <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.12.0</version> </dependency>

  • springtask 的使用方法和 cron 表达式解析

    spring 容器依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.5.RELEASE</version> </dependency> 开启任务注解驱动.即扫描的时候扫描 springtask 相关的注解. <?xml version=&qu

  • springboot Quartz动态修改cron表达式的方法

    1.概述: 在开发中有的时候需要去手动禁止和启用定时任务,修改定时任务的cron表达式然后再让其动态生效,之前有过SSM的类似的业务的开发但是忘记写下来了...只好重新温习了一次,加上最近比较流行springBoot所以升级了一下用springBoot来完成. 2.关联技术 SpringBoot.Quartz.H2.thymeleaf (好像就这么多) 3.具体流程 1)首先去手动创建一个调度器工厂对象-SchedulerFactoryBean;其实应该不用手动创建的但是为了顾及到业务的复杂性所

  • 浅谈springboot项目中定时任务如何优雅退出

    在一个springboot项目中需要跑定时任务处理批数据时,突然有个Kill命令或者一个Ctrl+C的命令,此时我们需要当批数据处理完毕后才允许定时任务关闭,也就是当定时任务结束时才允许Kill命令生效. 启动类 启动类上我们获取到相应的上下文,捕捉相应命令.在这里插入代码片 @SpringBootApplication /**指定mapper对应包的路径*/ @MapperScan("com.youlanw.kz.dao") /**开启计划任务*/ @EnableScheduling

  • Spring Boot如何实现定时任务的动态增删启停详解

    我以为动态停启定时任务一般用quartz,没想到还可以通过ScheduledTaskRegistrar来拓展.但是分布式场景,建议还是用quartz吧! 在 spring boot 项目中,可以通过 @EnableScheduling 注解和 @Scheduled 注解实现定时任务,也可以通过 SchedulingConfigurer 接口来实现定时任务.但是这两种方式不能动态添加.删除.启动.停止任务.要实现动态增删启停定时任务功能,比较广泛的做法是集成 Quartz 框架. 但是本人的开发原

  • SpringMVC Cron定时器Demo常见问题解决方案

    该技术的不适用的场景 如果在集群环境下,多台服务器中只希望有一台执行,那 Spring 自带的这种定时器方式可能不太符合你的需要. 但是,如果每台服务器都需要独立执行该定时器任务,且相互之间不存在同步,那么还是可以考虑的 SpringMVC 定时器 本文着重介绍的是 SpringMVC 配置定时器的方式,而不是 SpringBoot 配置定时器的方式. 注解方式 首先,在 Clock 类上添加 @Component,然后,在需要定时执行的方法上面加上 @Scheduled,最后指定 cron 表

  • Microsoft Sql server2005的安装步骤图文详解及常见问题解决方案

    一:安装sql server 2005过程中出现如下问题:"选择的功能中没有任何功能可以安装或升级": 解决方案:Microsoft SQL Server 2005→配置工具→SQL配置管理器→SQL Server 2005服务→右边的两个服务启动SQL Server FullTest Search() 和服务SQl Sever(计算机名) 二:无法将数CLSID写入\Software\Classes\PROTOCOLS\Handler\ms-help. 解决办法:退出电脑安全软件 三

  • SpringMVC请求/响应乱码问题解决方案解析

    这篇文章主要介绍了SpringMVC请求/响应乱码问题解决方案解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 GET请求乱码原因分析 GET请求参数是通过请求行中的URL发送给Web服务器(Tomcat)的. Tomcat服务器会对URL进行编码操作(此时使用的是Tomcat设置的字符集,默认是iso8859-1) 到了我们的应用程序中的请求参数,已经是被Tomcat使用ISO8859-1字符集进行编码之后的了. 解决方式 方式一 修改to

  • Golang cron 定时器和定时任务的使用场景

    目录 Golang cron 定时器和定时任务 timer和ticker的区别 Timer Ticker cron 定时任务 参考链接: Golang cron 定时器和定时任务 Golang中time包有两个定时器,分别为 ticker 和 timer.两者都可以实现定时功能,但各自都有自己的使用场景. timer和ticker的区别 ticker定时器表示每隔一段时间就执行一次,一般可执行多次. timer定时器表示在一段时间后执行,默认情况下只执行一次,如果想再次执行的话,每次都需要调用

  • Intellij搭建springmvc常见问题解决方案

    注意是maven的webapp: 选择maven下一步下一步. maven下载过慢在setting中加入镜像. 我也有疑问这是什么鬼格式,但是证明,格式不用调整,直接粘贴进去: <mirror> <id> nexus-aliyun </id> <mirrorOf> * </mirrorOf> <name> Nexus aliyun </name> <url> http://maven.aliyun.com/ne

  • SQL Server数据库安装时常见问题解决方案集锦

    本文我们总结了几个在安装SQL Server数据库时常见问题的解决方案,供初学者学习参考,接下来让我们来一起看一下吧. 常见问题一: 安装Sql Server 2000时出现"以前进行的程序创建了挂起的文件操作,运行安装程序之前,必须重新启动计算机" ,重启后仍然无效. 解决方案: 1.不用退出Sql Server 2000安装程序,直接切换到桌面. 2.打开注册表编辑器(在"运行"中敲入"regedit"之后回车即可),定位到注册表的HKEY_

  • Oracle常见问题解决方案汇总

    1.Oracle 11g ORA-12514:TNS:监听程序当前无法识别连接描述符中请求的服务 数据库服务器崩了,而且尝试重启服务和重启机器都解决不了问题 打开cmd窗口 C:\Users\hxt>sqlplus / as sysdba SQL*Plus: Release 11.2.0.1.0 Production on 星期三 12月 5 11:39:54 2018 Copyright (c) 1982, 2010, Oracle. All rights reserved. 已连接到空闲例程

  • docker中的环境变量使用与常见问题解决方案

    前言 docker可以为容器配置环境变量.配置的途径有两种: 在制作镜像时,通过ENV命令为镜像增加环境变量.在容器启动时使用该环境变量. 在容器启动时候,通过参数配置环境变量,如果与镜像中有重复的环境变量,会覆盖镜像的环境变量. 使用docker exec {containerID} env即可查看容器中生效的环境变量. [root@localhost ~]# docker exec 984 env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/

  • SpringMVC Tomcat控制台乱码问题解决方案

    关于SpringMVC运行Tomcat控制台出现乱码的情况(在网上找到一种方法亲测有效) 找到tomcat文件夹中的conf包下的logging.properties中找到 java.util.logging.ConsoleHandler.encoding = UTF-8 将这行代码注销改为 java.util.logging.ConsoleHandler.encoding = GBK 重启tomcat即可! 关于SpringMVC提交表单时,网页出现乱码情况,有两种解决方法 方法一(自定义过滤

  • Jmeter JDBC请求常见问题解决方案

    1. 时区设置问题 Cannot create PoolableConnectionFactory (The server time zone value '???��������??��??' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration propert

随机推荐