Dependency injection 我可以在quartz调度程序作业中使用CDI注入吗?

Dependency injection 我可以在quartz调度程序作业中使用CDI注入吗?,dependency-injection,glassfish,quartz-scheduler,glassfish-3,cdi,Dependency Injection,Glassfish,Quartz Scheduler,Glassfish 3,Cdi,我正在使用Glassfish和CDI进行注射,(大部分)成功。我似乎无法让Quartz作业与注入一起工作-用@Inject注释的bean永远不会被注入 Quartz是否使用某种不同的类加载器来防止注入发生 我在web.xml中这样配置Quartz: <context-param> <param-name>quartz:config-file</param-name> <param-value>quartz.properties<

我正在使用Glassfish和CDI进行注射,(大部分)成功。我似乎无法让Quartz作业与注入一起工作-用
@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>

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

上有一个quartz CDI集成库。我还没有尝试过。

我查看了@george armhold提到的github库,但发现它还不成熟

然而,我找到了另一个解决办法

查看此博客帖子:。它描述了一个类
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);
  }

}
创造就业机会 再看看这篇博文。只需使用
@Dependent
@ApplicationScoped
对它们进行注释(取决于您的用例),就可以了

不要忘记创建两个构造函数:一个公共无参数构造函数和一个公共构造函数,用
@Inject
和所需的bean作为参数进行注释。为了简洁起见,我将第一个构造函数设置为omnited

如果要使用
needle4j
进行测试,则只能使用带注释的
@Inject
字段进行注入。但你可以两者兼得,weld不会抱怨的

其他选择
你也可以看看。它还将处理其他CDI实现。如果您使用不同的实现(如JBoss、Websphere、Liberty Profile、TomEE、Glassfish等)在不同的应用程序服务器上运行应用程序,这将非常有用。

这里是对CDI扩展的良好描述。我尝试了上面建议的JobFactory实现,但在beanManager.getBeans(jobClazz)上的应用程序中失败.stream().findAny()语句。我尝试了一些变体来调整工作和工厂,然后放弃了这条路径,加入了Apache Deltaspike(但没有使用他们的@Scheduled注释),现在它可以工作了。读起来像是CDI问题,而不是石英的问题。我已经用了三年了。可能我的用户错误比我用焊接做的IDKWTF更多。但是你关于deltaspike的建议解决了我眼前的问题,所以谢谢!
/**
 * 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);
  }

}
@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
  }
}