前两天需要在以前的项目中添加quartz定时器功能
中间遇到了写问题 ,写在这里,以后方便查找
首先搭建基本的定时器操作
创建spring-mvc-quartz.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置JobDetail --> <bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="***************.quartz.JobTask"/> <property name="durability" value="true"/> </bean> <!-- 配置tirgger触发器 --> <bean id="cronTriggerFactoryBean" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <!-- jobDetail --> <property name="jobDetail" ref="jobDetail"/> <!-- cron表达式,执行时间 每天凌晨1点执行一次 --> <property name="cronExpression" value="0 0 1 * * ?"/> <!-- cron表达式,执行时间 每5秒执行一次 测试用--> <!--<property name="cronExpression" value="0/5 * * * * ?"/>--> </bean> <!-- 配置调度工厂 如果将lazy-init='false'那么容器启动就会执行调度程序 --> <bean id="springJobSchedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTriggerFactoryBean"/> </list> </property> <property name="jobFactory" ref="jobInstance"/> </bean> </beans>
首先创建Job任务,确认需要执行的定时的任务类
在创建触发器,定时时间为凌晨1点执行,可自行百度cron表达式修改
创建jobtask
@Component public class JobTask implements Job{ @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { ........ }
需要实现job类,重写execute方法
需要在将web.xml中引用spring-mvc-quartz.xml配置
以上定时也就配置完成了,但是我的项目中原本有shiro,启动一直会报错
Java.lang.InstantiationError: org.quartz.SimpleTrigger
经过查询才知道shiro实现的是针对quartz1.6版本的,在quartz2.2.1中SimppleTrigger为接口,无法实例化
查询别人的做法大部分都是重新创建实例:http://www.hillfly.com/2017/178.html
我觉的太麻烦了,采用了其他人的方法:https://blog.csdn.net/yangydq/article/details/79152379
上面说以后可能会出现问题,暂时还没发现,先这么写吧。。
private static final org.apache.shiro.mgt.SecurityManager securityManager = SpringContextHolder.getBean("securityManager");
在execute方法中添加
@Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { if (ThreadContext.getSecurityManager() == null){ ThreadContext.bind(securityManager); } ............ }
项目启动不会报错,但是发现spring的@Autowired无法注入问题
需要添加
public class QuartzJobFactory extends SpringBeanJobFactory { @Autowired private AutowireCapableBeanFactory beanFactory; /** * 这里覆盖了super的createJobInstance方法,对其创建出来的类再进行autowire。 */ @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { Object jobInstance = super.createJobInstance(bundle); beanFactory.autowireBean(jobInstance); return jobInstance; } }
在spring-mvc-quartz.xml中添加:
<!-- spring 注入使用 --> <bean id="jobInstance" class="com.jeeplus.modules.ordercenter.quartz.QuartzJobFactory"/>
<!-- 配置调度工厂 如果将lazy-init='false'那么容器启动就会执行调度程序 --> <bean id="springJobSchedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTriggerFactoryBean"/> <ref bean="cronTriggerWeekFactoryBean"/> </list> </property> <property name="jobFactory" ref="jobInstance"/> </bean>
这样spring的注入就可以使用了。
暂时没发现bug,不过说不准,可以暂时为解决方法,如果以后会出现问题,会在这里统一就是修改。