Spring与Quartz的整合实现定时任务调度
Spring 实现 整合 定时 quartz 任务调度
2023-09-14 08:57:45 时间
Quartz集成Spring的2个方法
关于Spring集成Quartz有2种方法:
1. JobDetailBean.
2. MethodInvokeJobDetailFactoryBean.
以下从自身使用和理解以及掌握的知识对其进行阐述。
需要注意的是,在使用Spring集成Quartz的时候,一定不要忘记引入spring-support这个包:
1、使用 MethodInvokeJobDetailFactoryBean
applicationTask.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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <!-- 定时任务 下游回调任务--> <!-- ======================== 1、定义需要执行的任务类。 ======================== --> <bean id="notifyQuartz" class="com.hsmpay.mobile.timerTask.NotifyTimerAction"> </bean> <!-- ======================== 2、将需要执行的定时任务注入JOB中。 ======================== --> <bean id="notifyQuartzDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <!--引入执行任务的类--> <property name="targetObject"><ref bean="notifyQuartz"/></property> <!--定义要执行具体类的方法--> <property name="targetMethod"><value>remoteNotify</value></property> </bean> <!-- ======================== 3、调度触发器 ======================== --> <bean id="notifyTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"><ref bean="notifyQuartzDetail"/></property> <property name="cronExpression"> <!--每五分钟执行一次--> <!--<value>0 08 10 * * ?</value>--> <value>0 0/5 * * * ?</value><!--<value>秒 分 时 天 月 周 年</value> 0 55 17 ? * MON-FRI--> </property> </bean> <!--================================================================================================--> <!-- 半分钟执行定时任务 --> <!-- ======================== 1、定义需要执行的任务类。 ======================== --> <bean id="messageTask" class="com.hsmpay.mobile.timerTask.MessageTask"></bean> <!-- ======================== 2、将需要执行的定时任务注入JOB中。 ======================== --> <bean id="oneMessageRollBackTaskJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"><ref bean="messageTask"/></property> <property name="targetMethod"><value>oneTaskJob</value></property> </bean> <!-- ======================== 3、调度触发器 ======================== --> <bean id="oneMessageStreamRollBackTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="oneMessageRollBackTaskJobDetail"/> </property> <property name="cronExpression"> <value>*/30 * * * * ?</value> </property> </bean> <!-- ======================== 4、调度工厂 ======================== --> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="notifyTrigger"/> </list> </property> </bean> <bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <!-- 线程池维护线程的最少数量 --> <property name="corePoolSize" value="10" /> <!-- 线程池维护线程所允许的空闲时间 --> <property name="keepAliveSeconds" value="200" /> <!-- 线程池维护线程的最大数量 --> <property name="maxPoolSize" value="50" /> <!-- 线程池所使用的缓冲队列 --> <property name="queueCapacity" value="100" /> <property name="rejectedExecutionHandler"> <!-- AbortPolicy:直接抛出java.util.concurrent.RejectedExecutionException异常 --> <!-- CallerRunsPolicy:主线程直接执行该任务,执行完之后尝试添加下一个任务到线程池中,可以有效降低向线程池内添加任务的速度 --> <!-- DiscardOldestPolicy:抛弃旧的任务、暂不支持;会导致被丢弃的任务无法再次被执行 --> <!-- DiscardPolicy:抛弃当前任务、暂不支持;会导致被丢弃的任务无法再次被执行 --> <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" /> </property> </bean> </beans>
相关代码配置
@Controller("notifyTimerAction") public class NotifyTimerAction { private Logger log = LoggerFactory.getLogger(this.getClass()); @Resource(name="transOrderService") TransOrderService transOrderService;//查询订单service //设置核心池大小 int corePoolSize = 5; //设置线程池最大能接受多少线程 int maximumPoolSize=20; //当前线程数大于corePoolSize、小于maximumPoolSize时,超出corePoolSize的线程数的生命周期 long keepActiveTime = 200; //设置时间单位,秒 TimeUnit timeUnit = TimeUnit.SECONDS; public String url ="http://localhost:8080/mobile/forwardPort/port.action"; /** * 下游回调通知,继续发送 */ public void remoteNotify() throws Exception{ log.debug("test定时任务启动了!!!!!!!!"); System.out.println("test定时任务启动了!!!!!!!!"); TransOrder order=new TransOrder(); order.setStatus(1);//设置成功状态 order.setClientType(7);//设置客户类型 7外放接口类型 order.setOrderTypeId(1L);//收款类型 //设置线程池缓存队列的排队策略为FIFO,并且指定缓存队列大小为5 BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(5); //创建ThreadPoolExecutor线程池对象,并初始化该对象的各种参数 ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepActiveTime, timeUnit,workQueue); try { List<TransOrder> orderList = transOrderService.searchEntityList(order); Map<String,Object> map=new HashMap<String,Object> (); //准备给下游发送数据 for(TransOrder transOrder:orderList){ Thread thread=new Thread(new Runnable() { public void run() { map.put("status",transOrder.getStatus());//交易状态 map.put("orderNum",transOrder.getOrderNum());//订单号 JSONObject jsonObject = JSONObject.fromObject(map); HttpClientUtil.submitPost(transOrder.getOtherData(), map.toString(), "UTF-8",60000, 60000); } }); executor.execute(thread); } executor.shutdown();//关闭线程池 } catch (Exception e) { e.printStackTrace(); throw e; } } }
==================================================================================================================================================================
二、JobDetailBean
1. 创建一个Job方法,此方法必须继承QuartzJobBean或者实现Job方法。
public class TestJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException { System.out.println(TimeUtils.getCurrentTime()); } }
2. 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"> <bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="com.mc.bsframe.job.TestJob"></property> <property name="durability" value="true"></property> </bean> <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> <property name="jobDetail" ref="jobDetail" /> <property name="startDelay" value="3000" /> <property name="repeatInterval" value="2000" /> </bean> <!-- 总管理类 如果将lazy-init='false'那么容器启动就会执行调度程序 --> <bean id="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <!-- 管理trigger --> <property name="triggers"> <list> <ref bean="simpleTrigger" /> </list> </property> </bean> </beans>
综上:定时任务的基本配置完成。
三、两种方法的说明
使用QuartzJobBean,需要继承。而使用MethodInvokeJobDetailFactoryBean则需要指定targetObject(任务实例)和targetMethod(实例中要执行的方法)
后者优点是无侵入,业务逻辑简单,一目了然,缺点是无法持久化(目前还不太清楚这点!)
从我使用的经验来说,我更推荐的第一种,其中一个很重要的原因就是因为定时任务中注入相关Service的时候,后者可以直接注入,而前者还需要进行Schedular的替换修改。
相关文章
- spring boot 使用aop实现拦截器
- spring学习笔记(20)数据库事务并发与锁详解
- 【Spring Boot】Spring Boot之两种引入spring boot maven依赖的方式
- 【Spring Boot】Spring Boot之整合Sharding-JDBC(java config方式)实现分库分表(水平拆分)
- ssh(Spring+Spring mvc+hibernate)——updateDept.jsp
- spring mvc: 多动作控制器(Controller下面实现多个访问的方法)MultiActionController / BeanNameUrlHandlerMapping
- 21-spring学习-springMVC实现CRUD
- Spring Boot 集成 Spring Security 入门案例教程
- Spring Boot 整合 Elasticsearch,实现 function score query 权重分查询
- Spring AOP实现 Bean字段合法性校验
- Spring的JDBC
- spring boot:spring security用mysql数据库实现RBAC权限管理(spring boot 2.3.1)
- spring boot:用redis+lua实现基于ip地址的分布式流量限制(限流/简单计数器算法)(spring boot 2.2.0)
- spring-boot 中实现标准 redis 分布式锁
- Spring+Velocity+Mybatis整合笔记(step by step)
- 不一样的视角来学习Spring源码之AOP---中
- Spring三级缓存
- Spring源代码学习之How is Beans.xml loaded and parsed
- 【spring】Spring Data --Spring Data JPA
- 深入理解 Redis Template及4种序列化方式__spring boot整合redis实现RedisTemplate三分钟快速入门
- 学习Spring Boot:(十四)spring-shiro的密码加密
- 利用spring实现服务启动就自动执行某些操作的2种方式
- Spring源码学习-PropertyPlaceholderHelper
- Spring的AOP配置文件和注解实例解析
- 【Spring注解驱动开发】你敢信?面试官竟然让我现场搭建一个AOP测试环境!
- 【java】Spring Boot --spring boot项目整合xxl-job