我正在使用Glassfish和CDI进行注入,(基本上)成功了。我似乎不能让Quartz job使用注入--使用@Inject注释的bean永远不会被注入。
Quartz是否使用了某种不同的类加载器来阻止注入的发生?
我在我的web.xml中这样配置Quartz:
<context-param>
<param-name>quartz:config-file</param-name>
<param-value>quartz.properties</param-value>
</context-param>
<context-param>
<param-name>quartz:shutdown-on-unload</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>quartz:wait-on-shutdown</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>quartz:start-scheduler-on-load</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>
org.quartz.ee.servlet.QuartzInitializerListener
</listener-class>
</listener>我的quartz.properties看起来像这样:
org.quartz.scheduler.instanceName = MyScheduler
org.quartz.scheduler.instanceId = 1
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames = quartz-config.xml
org.quartz.plugin.jobInitializer.scanInterval = 10
org.quartz.plugin.jobInitializer.wrapInUserTransaction = false
org.quartz.plugin.jobInitializer.failOnFileNotFound = true发布于 2018-05-16 19:40:37
我研究了@george-armhold提到的github库,但发现它还不成熟。
尽管如此,我还是找到了另一个解决方案。
看看这篇博文:DevSoap: Injecting CDI Managed Beans into Quartz Jobs。它描述了一个类CdiJobFactory.java,它将完成这项工作(用Groovy或Scala编写,但不能用kotlin或java编写)。
在java中实现
支持CDI的作业工厂
java中的相同CdiJobFactory:
/**
* CDI Job factory. Quartz will produce CDI managed beans.
*/
@ApplicationScoped
public class CdiJobFactory implements JobFactory {
@Inject
BeanManager beanManager;
@Override
public Job newJob(final TriggerFiredBundle bundle, final Scheduler scheduler) throws SchedulerException {
final Class<Job> jobClazz = (Class<Job>) bundle.getJobDetail().getJobClass();
final Bean<Job> bean = (Bean<Job>) beanManager.getBeans(jobClazz).stream().findAny().orElseThrow(IllegalStateException::new);
final CreationalContext<Job> ctx = beanManager.createCreationalContext(bean);
return (Job) beanManager.getReference(bean, jobClazz, ctx);
}
}在侦听器类中注入CDI Job Factory
现在,在将在启动时加载的侦听器类中,执行以下操作:
@ApplicationScoped
public class Listener implements ServletContextListener {
@Inject
public Listener(final CdiJobFactory jobFactory) {
this.jobFactory = jobFactory;
}
@Override
public void contextInitialized(final ServletContextEvent servletEvent) {
LOG.info("Initializing Listener");
try {
scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.setJobFactory(jobFactory);
} catch (final SchedulerException | RuntimeException schedEx) {
LOG.error("Problem loading Quartz!", schedEx);
}
// register your jobs here
}
}创造就业机会
再看看这篇博文。只需使用@Dependent或@ApplicationScoped (取决于您的用例)对它们进行注释,就可以了。
不要忘记创建两个构造函数:一个是公共的无参数构造函数,另一个是用@Inject和所需的bean作为参数注释的公共构造函数。为简洁起见,我省略了第一个构造函数。
如果您打算使用needle4j进行测试,则只能使用带注释的@Inject字段来提取注入。但你可以两者兼得,weld不会抱怨的。
其他替代方案
你也可以看看Apache Deltaspike。它还将处理其他CDI实现。如果您在具有不同实现(如JBoss、Websphere、Liberty Profile、TomEE、Glassfish等)的各种应用服务器上运行应用程序,这将非常有用。
发布于 2011-01-29 11:10:17
您需要创建自己的org.quartz.spi.JobFactory实现,以便知道如何使用应用程序的CDI来实例化作业类并注入它们。
发布于 2011-12-13 13:32:47
在github上有一个Quartz CDI集成库。我还没试过。
https://stackoverflow.com/questions/4812796
复制相似问题