最近在做后台运行Jobs的统计和监控。原本想写一个Job的基类,在基类中使用listener的方式解耦Jobs和监听的操作。
翻了翻Quartz的源码,发现Quartz本身已经有一整套完整的Listeners机制。分别在Job、Trigger、Scheduler三层都有Listener。
Quartz的Tutorial的Lesson 7 & 8提到了这些Listener接口:http://www.quartz-scheduler.org/docs/tutorial/index.html
但是Spring封装后如何使用这些Lisener,印象中Spring的文档中没有提到。回去翻了翻Spring文档,果然还是没有这方面的例子。
继续翻Spring源码。在SchedulerFactoryBean的基类SchedulerAccessor中,有如下方法
换句话说,就可以在配置SchedulerFactory的时候注入这些listener。针对我的需求,我实现了一个JobListener并将其加入GlobalJobListeners。上源码:
<bean id="notifyTopListener" class="com.oa.scm.app.task.listener.NotifyTopListener">
<!--
Top Path for production environment
<constructor-arg value="http://top.oa.com/"/>
-->
<constructor-arg value="http://nvwa.oa.com/~rayazhang/top_projccc/"/>
</bean>
<bean id="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="globalJobListeners">
<list>
<ref bean="notifyTopListener" />
</list>
</property>
<property name="triggers">
<list>
<!--
<ref bean="checkInTrigger" />
<ref bean="workflowWacthTrigger" />
<ref bean="cronPAdjMail" />
<ref bean="cronPtraceMail" />
<ref bean="cronAlarmNotify" />
<ref bean="svnPermissionTrigger" />
<ref bean="mailTaskWacthTrigger" />
<ref bean="cronSyncOAEmployeeTask" />
<ref bean="cronInitWebOnDatabase" />
<ref bean="cronAlarmCaseScan" />
<ref bean="cronAlarmCaseRemindMail" />
<ref bean="cronAlarmCaseScan" />
<ref bean="cronAlarmCaseScan" />
<ref bean="cronAlarmTask" />
<ref bean="cronWarnRemindProcessor" />
<ref bean="cronSensetivePersonProcessor" />
-->
<!--<ref bean="cronInventoryScheduleJobAssign" />
<ref bean="cronInventoryScheduleMail" />
<ref bean="cronInventoryTaskNotifyMail" />
<ref bean="cronInventoryTaskRemindMail" />
<ref bean="cronInventoryTaskResultMail" />
<ref bean="cronInventoryTaskChangeResposebleMail" />
<ref bean="OAFlowEventTask" />
<ref bean="cronAccessLogScan" />-->
</list>
</property>
</bean>
<bean id="notifyTopListener" class="com.oa.scm.app.task.listener.NotifyTopListener">
<!--
Top Path for production environment
<constructor-arg value="http://top.oa.com/"/>
-->
<constructor-arg value="http://nvwa.oa.com/~rayazhang/top_projccc/"/>
</bean>
<bean id="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="globalJobListeners">
<list>
<ref bean="notifyTopListener" />
</list>
</property>
<property name="triggers">
<list>
<!--
<ref bean="checkInTrigger" />
<ref bean="workflowWacthTrigger" />
<ref bean="cronPAdjMail" />
<ref bean="cronPtraceMail" />
<ref bean="cronAlarmNotify" />
<ref bean="svnPermissionTrigger" />
<ref bean="mailTaskWacthTrigger" />
<ref bean="cronSyncOAEmployeeTask" />
<ref bean="cronInitWebOnDatabase" />
<ref bean="cronAlarmCaseScan" />
<ref bean="cronAlarmCaseRemindMail" />
<ref bean="cronAlarmCaseScan" />
<ref bean="cronAlarmCaseScan" />
<ref bean="cronAlarmTask" />
<ref bean="cronWarnRemindProcessor" />
<ref bean="cronSensetivePersonProcessor" />
-->
<!--<ref bean="cronInventoryScheduleJobAssign" />
<ref bean="cronInventoryScheduleMail" />
<ref bean="cronInventoryTaskNotifyMail" />
<ref bean="cronInventoryTaskRemindMail" />
<ref bean="cronInventoryTaskResultMail" />
<ref bean="cronInventoryTaskChangeResposebleMail" />
<ref bean="OAFlowEventTask" />
<ref bean="cronAccessLogScan" />-->
</list>
</property>
</bean>
public class NotifyTopListener implements JobListener {
private static final Logger LOGGER = Logger.getLogger(NotifyTopListener.class);
private final String topPath;
public NotifyTopListener(String topPath) {
this.topPath = topPath;
}
@Override
public String getName() {
return this.getClass().getName();
}
@Override
public void jobExecutionVetoed(JobExecutionContext jobexecutioncontext) {
//Don't care job execution vetoed
}
@Override
public void jobToBeExecuted(JobExecutionContext jobexecutioncontext) {
notifyTop(jobexecutioncontext.getJobDetail().getName(), "start");
}
@Override
public void jobWasExecuted(JobExecutionContext jobexecutioncontext,
JobExecutionException jobexecutionexception) {
String jobName = jobexecutioncontext.getJobDetail().getName();
notifyTop(jobName, jobexecutionexception == null ? "finish" : "error");
}
private void notifyTop(String jobName, String status) {
try {
URL url = new URL(buildUrlString(jobName, status));
URLConnection openConnection = url.openConnection();
openConnection.setUseCaches(false);
openConnection.getInputStream();
} catch (IOException e) {
LOGGER.error("notify top failed while job " + jobName + " " + status, e);
}
}
private String buildUrlString(String jobName, String status) {
StringBuffer sb = new StringBuffer(topPath);
sb.append("apis/job_listener.php?job=");
sb.append(jobName);
sb.append("&status=");
sb.append(status);
return sb.toString();
}
}
public class NotifyTopListener implements JobListener {
private static final Logger LOGGER = Logger.getLogger(NotifyTopListener.class);
private final String topPath;
public NotifyTopListener(String topPath) {
this.topPath = topPath;
}
@Override
public String getName() {
return this.getClass().getName();
}
@Override
public void jobExecutionVetoed(JobExecutionContext jobexecutioncontext) {
//Don't care job execution vetoed
}
@Override
public void jobToBeExecuted(JobExecutionContext jobexecutioncontext) {
notifyTop(jobexecutioncontext.getJobDetail().getName(), "start");
}
@Override
public void jobWasExecuted(JobExecutionContext jobexecutioncontext,
JobExecutionException jobexecutionexception) {
String jobName = jobexecutioncontext.getJobDetail().getName();
notifyTop(jobName, jobexecutionexception == null ? "finish" : "error");
}
private void notifyTop(String jobName, String status) {
try {
URL url = new URL(buildUrlString(jobName, status));
URLConnection openConnection = url.openConnection();
openConnection.setUseCaches(false);
openConnection.getInputStream();
} catch (IOException e) {
LOGGER.error("notify top failed while job " + jobName + " " + status, e);
}
}
private String buildUrlString(String jobName, String status) {
StringBuffer sb = new StringBuffer(topPath);
sb.append("apis/job_listener.php?job=");
sb.append(jobName);
sb.append("&status=");
sb.append(status);
return sb.toString();
}
}
最后补充下,Spirng版本2.6.5,Quartz版本1.6.1
- 大小: 39.9 KB
分享到:
相关推荐
至于博文链接中的内容,虽然无法直接查看,但通常会包含如何在实际项目中设置Quartz集群和Spring Data集成的详细步骤,包括配置示例、代码示例以及可能遇到的问题和解决方案。 在使用过程中,可能会遇到如任务并发...
这一步通常是通过配置Quartz的`SchedulerFactoryBean`在Spring框架中完成的,或者在程序启动时手动执行。 对于更复杂的场景,比如需要支持集群或高可用性,可能还需要额外的表和设置。例如,`QRTZ_SCHEDULER_STATE`...
Quartz是一个功能强大的作业调度框架,而Spring则是Java领域中广泛使用的轻量级控制反转(IoC)容器。两者结合能够提供灵活、高效的任务调度解决方案。 #### 二、常见问题及解决方案 ##### 1. 对于`org.quartz....
在本篇讲解中,我们从代码示例出发,详细分析了如何使用Quartz进行任务调度,包括Job的定义、Trigger的配置以及自定义监听器的实现,希望能帮助读者更好地理解和应用Quartz。 以上内容覆盖了给定文件中标题和描述所...
在Servlet环境下,特别是在使用Spring MVC等框架时,Quartz与ServletContext的结合配置显得尤为重要,因为这能让我们更好地管理和监控后台定时任务。 ### Quartz简介 Quartz 提供了一个完全线程化的事件调度器,...
- JobDataMap是传递参数给Job实例的容器,可以在配置中设置,也可以在触发器中设置,供Job实例在执行时使用。 6. **并发控制** - Quartz支持并发执行策略,如并发限制、替换已存在的作业实例等。 7. **持久化** ...
这个"Spring Batch学习demo项目源码"是针对Spring Batch进行学习实践的一个实例,旨在帮助开发者了解并掌握如何在实际应用中使用Spring Batch。 在源码中,`batch-xml`文件可能是配置文件,通常在Spring Batch项目...
Java定时任务在软件开发中扮演着重要角色,它...在实际项目中,还可以结合Spring框架的集成,使Quartz的使用更加简便和高效。参考链接中的博客文章,可以获取更详细的步骤和示例代码,进一步提升你的Quartz实战能力。
Spring Batch是Spring生态体系中的一个核心组件,专为处理大量数据而设计,它提供了丰富的功能和高度可配置性,适用于各种批处理场景。下面将详细阐述Spring Batch的主要知识点。 一、Spring Batch基本概念 1. **...
在实际应用中,Quartz通常与其他工具或框架结合使用,如Spring框架,通过AOP(面向切面编程)来简化任务的注入和管理。 学习Quartz Scheduler,不仅需要理解其核心概念,还需要熟悉如何配置和使用,以及如何处理...
在分布式系统中,定时任务的管理变得复杂,Spring Boot 2可以通过集成Quartz或Spring Task来实现。Quartz是流行的开源作业调度框架,可以处理复杂的定时任务。而Spring Task是Spring框架内置的定时任务解决方案,...
Registering Servlets, Filters, and Listeners as Spring Beans 27.4.2. Servlet Context Initialization Scanning for Servlets, Filters, and listeners 27.4.3. The ServletWebServerApplicationContext 27.4.4....
标题中的“Spring批量工作fatura cartao credito:Job que gera a fatura dos clientes”表明这是一个使用Spring Batch框架开发的项目,目的是为信用卡客户生成账单。在Java开发领域,Spring Batch是一个强大的、...