我可以将 CDI 注入到quartz调度程序作业中吗?
我使用 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>
我的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
I'm using Glassfish and CDI for injection, (mostly) successfully. I can't seem to get Quartz jobs to work with injection- beans annotated with @Inject
never get injected.
Is Quartz using some kind of different classloader that's preventing injection from happening?
I'm configuring Quartz like so in my web.xml:
<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>
My quartz.properties looks like:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我查看了@george-armhold提到的github库,但发现它并不成熟。
尽管如此,我找到了另一个解决方案。
查看此博客文章:DevSoap:将 CDI 托管 Bean 注入石英作业。它描述了一个类
CdiJobFactory.java
,它将完成这项工作(用 Groovy 或 Scala 编写,但不是 kotlin 或 java)。中实现
在支持 CDI 的作业工厂
Java 中的相同 CdiJobFactory:
在侦听器类中注入 CDI 作业工厂
现在,在将在启动时加载的侦听器类中,执行以下操作:
创建作业
再次查看博客文章。只需用
@Dependent
或@ApplicationScoped
(取决于您的用例)注释它们就可以了。不要忘记创建两个构造函数:一个公共无参数构造函数和一个用
@Inject
注释的公共构造函数以及所需的 bean 作为参数。为了简洁起见,我提到了第一个构造函数。如果您要使用
needle4j
进行测试,则只会使用注释为@Inject
的字段来获取注入。但你可以两者兼得,焊接不会抱怨。其他替代方案
您还可以查看 Apache Deltaspike。它还将处理其他 CDI 实现。如果您在具有不同实现的各种应用程序服务器上运行应用程序(例如 JBoss、Websphere、Liberty Profile、TomEE、Glassfish 等),这非常有用。
I looked into the github library mentioned by @george-armhold, but found it not mature.
Nevertheless, I found another solution.
Take a look into this blog post: DevSoap: Injecting CDI Managed Beans into Quartz Jobs. It describes a class
CdiJobFactory.java
, which will do the job (written in either Groovy or Scala, but not kotlin or java).Implementation in java
CDI-capable Job Factory
Same CdiJobFactory in java:
Injection of CDI Job Factory in your listener classes
Now in your Listener class which will load on startup, do this:
Creating jobs
Look again at the blog post. Just annotate them with
@Dependent
or@ApplicationScoped
(depending on your use case) and you are fine.Don't forget to create two constructors: A public no-arg constructor and a public constructor annotated with
@Inject
and the needed beans as parameters. I omnited the first constructor for brevity.If you are going to test with
needle4j
, injections will only get picked up with a field annotated@Inject
. But you can have both, weld won't complain.Other alternatives
You can also take a look at Apache Deltaspike. It will also handle other CDI implementations. This is useful if you run your application on various application servers with different implementations (like JBoss, Websphere, Liberty Profile, TomEE, Glassfish, etc.).
您将需要自己实现 org.quartz.spi.JobFactory,它知道如何使用应用程序的 CDI 来实例化作业类并注入它们。
You will need to make your own implementation of org.quartz.spi.JobFactory that knows how to use your application's CDI to instantiate the jobs classes and inject them.
github 上有一个 Quartz CDI 集成库。还没试过。
There is a Quartz CDI integration library on github. Have not tried it yet.