我有一个在Wildfly上运行的Java EE应用程序,我想将其与Quartz Scheduler集成在一起。这就是我设想从Quartz作业中调用EJB的方式(由于我在编译时不知道EJB类的名称,因此我使用了查找):
public class MyJob implements Job {
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
InitialContext ic = new InitialContext();
MyInterface bean = null;
try {
String beanClassName = getItFromSomewhere();
bean = (MyInterface) ic.lookup("java:module/" + beanClassName );
}
catch (NamingException e) {
e.printStackTrace();
}
bean.myMethod();
}
}
这种方法正确吗?容器在什么时候不知道Quartz作业 它启动了,这是一个问题吗?
答案 0 :(得分:2)
一个更干净的替代方案是通过EJB
的{{1}}传递Job
实例
准备JobExecutionContext
Job
在final JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put(MY_INTERFACE, myInterface);
final Job myJob =
JobBuilder.newJob(MyJob.class)
.setJobData(jobDataMap)
.build();
内
Job#execute
Quartz final JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
final MyInterface myInterface = (MyInterface) jobDataMap.get(MY_INTERFACE);
实现不应在运行它的所有JavaEE容器中都知道。从长远来看,这将简化更新代码/体系结构的过程。
此外,您的Job
应该只关心其唯一的职责,而不是获取所需的依赖项。
将Job
视为一种奇怪的依赖注入。
答案 1 :(得分:0)
这是Quart'z开发人员在GitHub上提供的答案:
总结:您的方法是正确的,在MyJob类中,您正确创建了InitialContext()来搜索要调用的EJB实例。 如上一个答案所建议的那样,您不能将EJB实例放入JobContext中,因为如果在Job的调度和调用之间有服务器重新启动,则不能保证您想要的EJB实例会在JobContext中被“注入”。