首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我可以使用CDI注入到quartz-scheduler作业中吗?

我可以使用CDI注入到quartz-scheduler作业中吗?
EN

Stack Overflow用户
提问于 2011-01-27 12:36:55
回答 3查看 4.6K关注 0票数 5

我正在使用Glassfish和CDI进行注入,(基本上)成功了。我似乎不能让Quartz job使用注入--使用@Inject注释的bean永远不会被注入。

Quartz是否使用了某种不同的类加载器来阻止注入的发生?

我在我的web.xml中这样配置Quartz:

代码语言:javascript
复制
<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看起来像这样:

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

发布于 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:

代码语言:javascript
复制
/**
 * 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

现在,在将在启动时加载的侦听器类中,执行以下操作:

代码语言:javascript
复制
@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等)的各种应用服务器上运行应用程序,这将非常有用。

票数 3
EN

Stack Overflow用户

发布于 2011-01-29 11:10:17

您需要创建自己的org.quartz.spi.JobFactory实现,以便知道如何使用应用程序的CDI来实例化作业类并注入它们。

票数 2
EN

Stack Overflow用户

发布于 2011-12-13 13:32:47

github上有一个Quartz CDI集成库。我还没试过。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4812796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档