最后,我有时间为所有其他可能不得不使用 Quartz 作为在 jboss 中运行的服务的人写下这一切。但也可以尝试@Tomasz 在他的回答中提到的其他选项。
请注意,如果您尝试从绑定它的 JBoss 服务器外部检索它,您将得到一个空引用。如果您有这样的要求,您可能需要考虑使用 Quartz 的 RMI 支持。
1)首先确保你删除了 jboss/[profile]/lib 或 jboss 发行版附带的 quartz.rar 中任何现有的石英版本。
2)请将您的quartz.1.8.3.jar &quartz-jboss.1.8.jar 放入accesmanager/[profile]/lib
3)下面是quartz-service.xml的代码,需要放在jboss deploy文件夹中,它将启动Quartz调度程序:
<server>
<mbean code="org.quartz.ee.jmx.jboss.QuartzService"
name="user:service=QuartzService,name=QuartzService">
<attribute name="JndiName">Quartz</attribute>
<attribute name="Properties">
org.quartz.scheduler.instanceName = BGSScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.xaTransacted = false
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 4
org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer = true
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreCMT
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource = QUARTZ
org.quartz.dataSource.QUARTZ.jndiURL = java:FmManagerDS
org.quartz.jobStore.nonManagedTXDataSource = QUARTZ_NO_TX
org.quartz.dataSource.QUARTZ_NO_TX.jndiURL = java:FmManagerDS
</attribute>
<depends>jboss.jca:service=DataSourceBinding,name=FmManagerDS</depends>
</mbean>
</server>
] 大多数事情都是不言自明的,或者您可以在Quartz Configuration获得更多详细信息
。关键是要注意,quartz 需要 2 个数据源。一个是容器管理的数据源 - 与 jboss *-ds.xml( java:FmManagerDS 在我的例子中)。如果您的 'org.quartz.jobStore.dataSource' 是 XA,则将 'org.quartz.jobStore.nonManagedTXDataSource' 设置为非 XA 数据源(对于同一数据库)。否则,您可以将它们设置为相同。
然后在spring applicationContext中,我必须得到quartz的句柄,这样我才能注入到wrapperScheduler。下面的代码
<bean id="quartzScheduler" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>Quartz</value>
</property>
</bean>
<bean id="wrapperScheduler" class="k.fa.quartz.schedule.ServiceScheduler">
<property name="scheduler">
<ref bean="quartzScheduler" />
</property>
</bean>
然后我们可以使用以下方式安排作业
Timestamp t = new Timestamp (System.currentTimeMillis());
ScheduleJob job = new ScheduleJob(EmailJob.class.getCanonicalName() +t.toString(), EmailJob.class);
下面是将 spring applicationContext 传递给 EmailJob 的代码,以便我们可以访问 bean 和其他东西。为了实现这一点,我们需要实现 ApplicationContextAware 接口,以便 applicationContext 可用,然后将其推送到 schedulerContext。请确保我们不要将 applicationContext 放入 JobdataMap 以防您使用 JDBC 存储,因为它会产生序列化问题。
serviceScheduler.getScheduler().getContext().put("applicationContext", ctx);
serviceScheduler.scheduleCronJob(job, "test" + t.toString(), ServiceScheduler.DEFAULT_TRIGGER_GROUP, cronExpression);
其他不使用 wrapperscheduler 的人可以类似地使用以下方法将石英的句柄直接放入他们的代码中
InitialContext ctx = new InitialContext();
Scheduler scheduler = (Scheduler) ctx.lookup("Quartz");
ScheduleJob job = new ScheduleJob(EmailJob.class.getCanonicalName() +t.toString(), Executor.class);
scheduler.scheduleJob(job, trigger);
在电子邮件作业类中,您可以使用下面来获取 applicationContext
applicationContext = (ApplicationContext) context.getScheduler().getContext().get(APPLICATION_CONTEXT_KEY);
//get spring bean and do the necessary stuff
另一个重要的事情是,由于quartz 调度程序在web 应用程序之外运行,如果它在war 内部,quartz 将无法触发jobclass。它需要在jboss/[profile]/lib 中的共享jar 中。