在Java Web应用程序中使用Google Guice/Dogger在Quartz Job执行中创建对象链



我开始在Java web应用程序中使用Quartz创建一个cron作业,以执行其中一个清理任务。实际作业按预期解雇,没有Quatrz作业执行问题。从下面的代码片段中,当我尝试使用MyService作为作业的一部分来调用所需的方法时,Dependency不起作用。

没有创建MyService类的对象。所以我得到了一个空指针异常。为了避免这种情况,我尝试使用Google Guice(也尝试了dogger(来管理依赖项注入,但MyService对象的创建依赖于其他类。

比方说,在这个例子中,CustomerService和这个CustomerService依赖于其他类,而这些类依赖于其他一些类等等。所以我最终将使用Guice或Dogger创建对象创建链。

代码片段:

import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import org.quartz.Job;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;

@Singleton
public class CustomJobFactory implements JobFactory {

@Inject
private Injector injector;

@Override
public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
return (Job) injector.getInstance(bundle.getJobDetail().getJobClass());
}
}

public class QuartzJobHelper  {
private final Scheduler scheduler;

@Inject
public QuartzSchedulerImpl(Scheduler scheduler, CustomJobFactory customJobFactory) {
this.scheduler = scheduler;
try {
this.scheduler.setJobFactory(customJobFactory);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
public static void executeJob() throws Exception {
// The Guice injector used to create instances.
Injector injector = Guice.createInjector(new MyModule());
JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("myjob", "mygroup")
.build();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("mytrigger", "mygroup")
.withSchedule(CronScheduleBuilder.cronSchedule("0/1 * * * * ?")).build();
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
// Inform Quartz scheduler to use our factory.
scheduler.setJobFactory((injector.getInstance(CustomJobFactory.class));
scheduler.scheduleJob(jobDetail, trigger);
// Start the scheduler.
scheduler.start();
}

}

导入org.quartz.spi.JobFactory;导入java.io.IOException;

public class MyModule extends AbstractModule {

@Override
protected void configure() {
bind(JobFactory.class).to(MyJobFactory.class);
bind(MyService.class).to(MyServiceImpl.class);
bind(CustomerService.class).to(CustomerServiceImpl.class);
bind(MyDao.class).to(MyDaoImpl.class);
bind(CustomCache.class).to(CustomCacheImpl.class);
bind(ProxyDao.class).to(ProxyDaoImpl.class);
bind(RequestDao.class).to(DefaultRequestDao.class);
|
|
|
etc.. Likewise so many dependencies are there to inject but finding 100's of dependencies.

}
}
public class MyJob extends org.quartz.Job {
@Inject
MyService service;
public void execute(JobExecutionContext jobContext) throws JobExecutionException {
service.cleanupJunkData();
}    
}
class MyService {
void cleanupJunkData();
}
@Named
class MyServiceImpl implments MyService {

private CustomerService cs; 
private MyDao dao;
private CustomCache cache;

@Inject 
public MyServiceImpl(CustomerService cs, MyDao dao, CustomCache cache) {
this.cs = cs;
this.dao=dao;
this.cache = cache;
}

@Override
public void cleanupJunkData() {
List<Customer> customerData = cs.getCustomerData(dao.getExpiredCustId());
cache.clear(customerData);
}
}
public Class MainClass {
public static void main(Stirng[] args) {
QuartzJobHelper.executeJob();
}
}

有人能建议如何在Quartz工作中处理对象创建吗?

您的示例中没有提供任何特定于Guice的代码,但您希望创建一个JobFactory,它将负责在每个作业被激发时注入:

public class GuiceJobFactory implements JobFactory {
@Inject
private Injector guiceInjector;

@Override
public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
return (Job) guiceInjector.getInstance(bundle.getJobDetail().getJobClass());
}
}

你可以随心所欲地创建它,但你需要以某种方式将Injector放入其中

编辑

从你的评论来看,我真的不明白。我们有以下设置(具有多个作业(:

JobThatDoesSomething:
@Inject Service1 service1;
Service1:
@Inject Dao1 dao1;
@Inject Dao2 dao2;
@Inject ValidationFactory validationFactory;
ValidationFactory:
@Inject ValidationProvider provider;

这是一个高层次的层次结构,只是一个单一的工作。我们有大约100个具有相同级别的注入依赖项。据我所知,这和你完全一样吗?

你在说什么?这家工厂是你的:

  • MyService没有注入
  • MyService。CustomerService未注入
  • 等等

编辑2

你需要以某种方式创建你的注射器。我添加了您的主代码,并举例说明如何使用CustomModuleJobFactory:

public Class MainClass {
public static void main(Stirng[] args) {
// You need to create your injector here
Injector injector = Guice.createInjector(new CustomModule());
SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
Scheduler scheduler = schedFact.getScheduler();
scheduler.setJobFactory(new GuiceJobFactory(injector));  // Use it here
scheduler.start();

// define the job and tie it to our HelloJob class
JobBuilder jobBuilder = JobBuilder.newJob(MyJob.class);
JobDataMap data = new JobDataMap();
data.put("latch", this);

JobDetail jobDetail = jobBuilder.usingJobData("example", "com.QuartzSchedulerExample") 
.usingJobData(data)
.withIdentity("myJob", "group1")
.build();


// Fire at curent time + 1 min every day
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "group1")
.startAt(DateBuilder.todayAt(10, 20, 20))
.withSchedule(CronScheduleBuilder.cronSchedule("0 " + (min + 1) + " " + hour + " * * ? *"))     
.build();

// Tell quartz to schedule the job using our trigger
scheduler.scheduleJob(jobDetail, trigger);
}
}

最新更新