前言
本来想在毕设上实现一个提前一天自动提醒的功能
①交给tomcat监听:但是在tomcat启动时就会报错,因为想使用监听器通过spring去监听数据库,tomcat会先初始化监听器其次是过滤器然后是你的代码,所以Spring还没开始接管就访问数据库就会报错!
②前端ajax定时刷新请求:在foot页面定时发起一个请求,若请求在后端验证(是不是每日早上8点啊之类的...),验证成功就开启另外一个线程去访问数据库(用注解是访问不到的,因为主线程中的spring配置了bean,在另外一个线程就需要重新读取applicationContext.xml配置文件,然后这个类继承线程类重写方法,在方法中写好处理逻辑即可。
③上面那种方法也能实现,可能我感觉效果不好,又可能我感觉那种方法太笨,经过翻阅许多博客发现其实定时任务能很好的解决我这个问题,就尝试去try,或许我太笨,但是查找多个博客要么就是搬运要么就是出现一些奇奇怪怪的bug,导致很多博客内容看似没问题但是出现了一些小问题....
正文:SSM如何整合Quartz?
首先要考虑到定时任务都放到SSM中了,肯定是被spring接管,还要考虑到如何在一启动Tomcat就得开始定时任务,考虑到这些问题之后就可以开始了...
第一:导入依赖。
这一步是第一步也是极为重要的一步,考虑到要想使Quartz依赖生效,它还依赖于另外两个依赖(spring-context、spring-context-support),另外就是版本问题,不一样的版本可能会导致出现找不到类的异常。目前我导入的依赖是如下所示:
<!-- spring-context核心类和核心支持类 spring-webmvc spring-jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.16</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.3.16</version>
</dependency>
<!-- 定时任务-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
参考文章:定时任务轮询报错:Cannot find class [org.springframework.scheduling.quartz.CronTriggerBean]_Lu、ck的博客-CSDN博客
第二:编写配置文件 spring-quartz.xml 文件
依赖导入后,要注意工件中的lib包下是否有该依赖,确认无误后,编写配置文件,通过spring管理定时任务。因为最终在web.xml中监听的applicationContext.xml文件,所以还需要将该配置文件引入到applicationContext.xml文件中。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.lsq.utils" />
<!-- 注入任务处理类bean -->
<bean id="myJob" class="com.lsq.utils.MyJob"></bean>
<!-- 任务触发器详细信息bean -->
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="myJob"></property>
<property name="targetMethod" value="runJob"></property>
<property name="concurrent" value="false" /><!-- 作业不并发调度 -->
</bean>
<!-- <bean id="otherDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">-->
<!-- <property name="targetObject" ref="otherJob"></property>-->
<!-- <property name="targetMethod" value="execute"></property>-->
<!-- <property name="concurrent" value="false" /><!– 作业不并发调度 –>-->
<!-- </bean>-->
<!-- 定义trigger 触发器 -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="jobDetail"></property>
<property name="cronExpression" value="0/5 * * * * ?"></property>
</bean>
<!-- <bean id="otherTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">-->
<!-- <property name="jobDetail" ref="otherDetail"></property>-->
<!-- <property name="cronExpression" value="${crond.otherJob}"></property>-->
<!-- </bean>-->
<!-- 设置触发器调度工厂 -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger"/>
<!-- <ref bean="otherTrigger"/>-->
</list>
</property>
</bean>
</beans>
第三:编写任务类
第二步的配置文件中注入的任务类需要指定类和具体的方法。
package com.lsq.utils;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component("MyJob")
public class MyJob {
public void runJob() {
/**
* 定时任务的具体逻辑,本处以每五秒输出时间为例
*/
System.out.println("现在的时间是:"+new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss").format(new Date()));
}
}
其中触发器中有着控制如何定时的功能(几月几号什么时间每隔多久干什么事.......)此处不做过多解释,叫 Corn表达式可以通过以下链接自行理解: