我设法在Spring中使用JobStoreTX持久存储来配置和调度Quartz作业.我不使用Spring的Quartz作业,因为我需要在运行时动态调度它们,并且我发现Spring与Quartz集成的所有示例都是对Spring配置文件中的shcedules进行硬编码...无论如何,这里是如何我安排工作:
JobDetail emailJob = JobBuilder.newJob(EMailJob.class)
.withIdentity("someJobKey", "immediateEmailsGroup")
.storeDurably()
.build();
SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger()
.withIdentity("someTriggerKey", "immediateEmailsGroup")
.startAt(fireTime)
.build();
// pass initialization parameters into the job
emailJob.getJobDataMap().put(NotificationConstants.MESSAGE_PARAMETERS_KEY, messageParameters);
emailJob.getJobDataMap().put(NotificationConstants.RECIPIENT_KEY, recipient);
if (!scheduler.checkExists(jobKey) && scheduler.getTrigger(triggerKey) != null) {
// schedule the job to run
Date scheduleTime1 = scheduler.scheduleJob(emailJob, trigger);
}
Run Code Online (Sandbox Code Playgroud)
EMailJob是一个简单的工作,它使用Spring的JavaMailSenderImpl类发送电子邮件.
public class EMailJob implements Job {
@Autowired
private JavaMailSenderImpl mailSenderImpl;
public EMailJob() {
}
public void execute(JobExecutionContext context)
throws JobExecutionException {
....
try {
mailSenderImpl.send(mimeMessage);
} catch (MessagingException e) {
.... …Run Code Online (Sandbox Code Playgroud) 我知道有一个重复这里,这可能正是我的情况下,虽然它会值得一些更好的解释,我会尝试在这里提供.
我使用Spring应用程序上下文使用Java Web应用程序.在这种情况下,我使用Quartz定义了预定作业.这些作业由.properties文件中定义的cron触发.
Spring上下文嵌入在war中,而.properties文件位于应用程序服务器上(在这种特殊情况下为Tomcat).
这很好,允许根据环境(开发,集成,生产......)定义不同的crons.
现在,在我自己的计算机上本地运行此应用程序时,我不希望执行这些作业.有没有办法写一个永远不会触发的cron表达式?
有没有人找到任何替代Quartz的开源解决方案,他们很满意?
我知道Cronacle是一个备受尊重(且价格昂贵)的闭源解决方案,用于作业调度,但我想确保在走下这条路线之前耗尽开源替代品.
我有一个Java程序,每20秒从Spring Qquartz执行一次.有时执行只需几秒钟,但随着数据变大,我确信它会运行20秒或更长时间.
当一个实例仍在执行时,如何防止Quartz触发/触发作业?在数据库上执行2个执行相同操作的作业并不是那么好.有没有办法可以做某种同步?
这应该很容易.我正在使用在Apache Tomcat 6.0.18下运行的Quartz,我有一个jobs.xml文件,它设置我每分钟运行的预定作业.
我想做的是,如果在下一个触发时间到来时作业仍然在运行,我不想开始新的工作,所以我可以让旧实例完成.
有没有办法在jobs.xml中指定它(防止并发实例)?
如果没有,有没有办法可以在我的应用程序的Job实现中共享对内存中单例的访问权限(这是通过JobExecutionContext吗?)所以我可以自己处理并发?(并检测先前的实例是否正在运行)
更新:在文档中徘徊之后,这是我正在考虑的几种方法,但要么不知道如何让它们工作,要么存在问题.
使用StatefulJob.这可以防止并发访问...但我不确定如果我使用它会发生什么其他副作用,我也想避免以下情况:
假设触发时间是每分钟,即触发器#0 =在时间0,触发器#1 = 60000毫秒,#2 = 120000,#3 = 180000等,并且在时间0的触发器#0触发我的工作需要130000毫秒.使用普通Job,这将执行触发器#1和#2,而作业触发器#0仍在运行.使用StatefulJob,这将按顺序执行触发器#1和#2,紧接在#0结束于130000之后.我不希望这样,我希望#1和#2不运行,并且下一个运行作业的触发器应该发生在#3(180000毫秒).所以我仍然需要使用StatefulJob做其他事情才能让它以我想要的方式工作,所以我认为使用它并没有多大优势.
使用TriggerListener从vetoJobExecution()返回true.
虽然实现接口似乎很简单,但我必须弄清楚如何以声明方式设置TriggerListener的一个实例.找不到xml文件的文档.
使用static我的类所拥有的共享线程安全对象(例如信号量或其他)来实现Job.
我不喜欢通过staticTomcat/Quartz下的关键字使用单例的想法,不确定是否有副作用.另外,我真的不希望它们成为真正的单身,只是与特定工作定义相关的东西.
实现我自己的Trigger,它扩展了SimpleTrigger并包含可以运行自己的TriggerListener的共享状态.
同样,我不知道如何设置XML文件以使用此触发器而不是标准<trigger><simple>...</simple></trigger>.
我正在阅读关于调度的Spring 3.0文档.我倾向于Spring的JobDetailBean for Quartz.但是@Scheduled注释引起了我的注意.看来这是使用Spring Framework调度任务的另一种方式.基于文档,Spring提供了三种调度方式:
我对JDK Timer没兴趣.我为什么要选择@Scheduled而不是Quartz?(当我提到Quartz时,我的意思是使用Spring的bean包装器进行Quartz).
假设我的用例非常复杂,我将与第三方Web服务进行通信,以便按指定的时间间隔导入和导出数据.
Quartz Scheduler中每个格林尼治标准时间午夜12点运行程序的cron表达式是什么.
我之前从未使用过石英,所以我还在学习.
是表达式0 0 12 * * ?还是表达式12 pm (noon).有谁能告诉我?
我想在java动态Web应用程序中使用Quartz 2.2创建一个调度程序.我是这项任务的新手.我尝试了网络上的所有教程.我尝试上下文监听器方法来初始化调度程序.它似乎不起作用.hello world程序仅适用于一般的java应用程序.对于Web应用程序,它看起来很棘手.
pom.xml中:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test.ananth</groupId>
<artifactId>test-app</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>test-app Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>servlet-api</artifactId>
<version>6.0.30</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>test-app</finalName>
</build>
Run Code Online (Sandbox Code Playgroud)
quartz.properties:
#org.quartz.scheduler.instanceName = MyScheduler
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
# Main Quartz configuration
org.quartz.scheduler.skipUpdateCheck = true
org.quartz.scheduler.instanceName = MyQuartzScheduler
org.quartz.scheduler.jobFactory.class = org.quartz.simpl.SimpleJobFactory
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool …Run Code Online (Sandbox Code Playgroud) 我正在开发一个应用程序(Quartz调度程序),我们有一个工作类负责实际执行工作,我们需要在Quartz调度程序中创建触发器时告诉/传递作业类的名称.
我想为所有想要使用API的人提供一个扩展点(除了我将作为API的一部分提供的一些通用作业).我们的想法是创建一个(标记)接口,如果有人想要将它们的类声明为调度程序作业类,那么他们所要做的就是(声明)实现接口.
我不确定如何找到遵循合同的类(通过实现接口),以便我可以向想要在调度程序中安排触发器的用户显示它们.
我的要求是不在运行时加载类,而是显示实现所需接口的类的用户列表,以便用户可以选择类和类名称可以传递给调度程序.这是Quartz调度程序,它最终将负责创建类的实例.
任何人都可以建议我如何实现上述目标,还是有任何其他更好的方法来实现我想要做的事情?
编辑
我浏览了ServiceLoader的文档,似乎为了实现一个服务,我必须在META-INF文件夹中创建一个具有实现类名称的文件,这使我认为如果我的API的用户想要20个不同的实现,他必须在文件中放入20个条目,这对我来说似乎为最终用户做了很多额外的工作,因为每个工作类将被创建用于执行特定的工作,并且可以有100个工作类.
如果我的假设错了,请纠正我.
我正在使用石英和弹簧,我想在工作类中注入/使用另一个类,我不知道如何正确地做到这一点
xml:
<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-2.5.xsd">
<!-- Scheduler task -->
<bean name="schedulerTask" class="com.mkyong.quartz.SchedulerTask" />
<!-- Scheduler job -->
<bean name="schedulerJob"
class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.mkyong.quartz.SchedulerJob" />
<property name="jobDataAsMap">
<map>
<entry key="schedulerTask" value-ref="schedulerTask" />
</map>
</property>
</bean>
<!-- Cron Trigger -->
<bean id="cronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="schedulerJob" />
<property name="cronExpression" value="0/10 * * * * ?" />
</bean>
<!-- Scheduler -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobDetails">
<list>
<ref bean="schedulerJob" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="cronTrigger" />
</list>
</property>
</bean>
</beans> …Run Code Online (Sandbox Code Playgroud) quartz-scheduler ×10
java ×6
spring ×5
concurrency ×1
cron ×1
inject ×1
java-ee ×1
maven ×1
scheduling ×1
spring-mvc ×1
tomcat7 ×1