从quartz作业调用应用程序作用域中的方法

时间:2016-04-02 12:55:45

标签: jsf tomcat callback quartz-scheduler

我有一个应用程序范围的bean

@ManagedBean(name = "myController")
@ApplicationScoped
public class MyController implements Serializable{
...
public void allOn(){...}

我想从石英作业中调用allOn()方法

import org.quartz.Job;
public class CronJobAllOn implements Job{
     @Override
     public void execute(..){
          //call allOn();}
}

我尝试通过JobDataMap将FacesContext传递给Job-Class

JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("facesContext", FacesContext.getCurrentInstance());
JobDetail job = newJob(CronJobAllOn.class)
        .usingJobData(jobDataMap)
        .withIdentity("job1", "group1") 
        .build();

但是当我尝试在CronJobAllOn类中调用它时,它只会抛出IllegalStateException

public void execute(JobExecutionContext context) throws JobExecutionException {
     FacesContext fc= (FacesContext) context.getMergedJobDataMap().get("facesContext");
     MyController test  = (MyController)fc.getExternalContext().getApplicationMap().get("MyController");
     test.allOn();}

如何从石英作业中调用MyController中的allOn()方法?

1 个答案:

答案 0 :(得分:1)

我得到了我的问题的解决方案,BalusC的简短评论让我走上了正确的道路。 我切换到TomEE,获得CDI。

要在我的工作中使用CDI-Bean注入,我必须创建自己的JobFactory类:

public class CdiJobFactory implements JobFactory {

@Inject
@Any
private Instance<Job> jobs;

@Override
public Job newJob(TriggerFiredBundle triggerFiredBundle, Scheduler scheduler) throws SchedulerException {
    final JobDetail jobDetail = triggerFiredBundle.getJobDetail();
    final Class<? extends Job> jobClass = jobDetail.getJobClass();

    for (Job job : jobs) {
        if (job.getClass().isAssignableFrom(jobClass)) {
            return job;
        }
    }

    throw new RuntimeException("Cannot create a Job of type " + jobClass);
}

创建工厂

Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.setJobFactory(cdiJobFactory);

之后我能够注入myController:

public class CronJobAllOn implements Job{

@Inject
private MyController mc;

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {

    mc.allOn();

}