如何使用Dagger 2在Quartz作业中注入依赖项

Iva*_*nov 3 java quartz-scheduler dagger-2

我使用Dagger 2作为我的DI框架,并为其提供了一个singleton类实例。

我还使用Quartz Scheduler来调度作业。有什么方法可以将单例类注入Quartz作业吗?

Dagger 2模块:

@Module
public class MyModule {

    @Provides
    @Singleton
            Messager provideMessager() {

        return new CustomMessager();
    }
}
Run Code Online (Sandbox Code Playgroud)

匕首2组件:

@Component(modules = MyModule.class)
@Singleton
public interface MyComponent {

    Messager messager();
}
Run Code Online (Sandbox Code Playgroud)

石英作业:

public class MyJob implements Job {

    // @Inject
    Messager messager;

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

        messager.sendMessage("Hello.");
    }

}
Run Code Online (Sandbox Code Playgroud)

编辑

我创建了一个MyJobScheduler调用Quartz Job的类:

    public class MyJobScheduler {


        public void scheduleJob() {

            JobDetail myJob = JobBuilder.newJob(MyJob.class)
                                            .withIdentity("myJobId", "Group1")
                                            .build();

            Trigger trigger = TriggerBuilder.newTrigger()
                                            .withIdentity("myTriggerId", "Group1")
                                            .startNow()
                                            .build();

                Scheduler scheduler = new org.quartz.impl.StdSchedulerFactory().getScheduler();

                scheduler.start();


    scheduler.scheduleJob(myJob, trigger);

    }
}
Run Code Online (Sandbox Code Playgroud)

编辑2

因此,我设法对其进行了配置,但我不知道这是否是正确的方法。

首先,我创建了一个DependencyResolver类,将其用作单例:

public class DependencyResolver {

    private static DependencyResolver _instance = null;

    private static MyComponent _myComponent;

    public static MyComponent getMyComponent() {
        return _myComponent;
    }

    protected DependencyResolver() {
        // Exists only to defeat instantiation.
    }

    public static void initialize() {

        _myComponent = DaggerMyComponent.builder().build();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我在方法中调用了initialize main方法:

DependencyResolver.initialize();

MyComponent myComponent = DependencyResolver.getMyComponent();
Run Code Online (Sandbox Code Playgroud)

DependencyResolver在MyJob类中使用了Messager单例实例。

public class MyJob implements Job {

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

    MyComponent myComponent = DependencyResolver.getMyComponent();

    Messager messager = myComponent.messager();
    messager.sendMessage("Hello.");
    }
}
Run Code Online (Sandbox Code Playgroud)

这是解决此问题的正确方法吗?任何输入将不胜感激。

G. *_*ard 5

您的EDIT 2 DependencyResolver方法克服了使用Dagger注入依赖项的全部原因,因为您的工作从单例提供程序获取依赖项。:-)它完全绕过了Dagger的好处,因此您最好在源依赖项本身上添加一个单例,例如:Messager messager = CustomMessager.getInstance()或类似的东西。

使用依赖注入的原因之一是协助单元测试,在这种情况下,您将失去在单元测试中模拟Messager实现的功能。

JobFactoryAPI文档中提到了将依赖注入与Quartz作业一起使用的正确方法:“该接口可能对那些希望其应用程序通过某些特殊机制生成Job实例的人有用,例如为依赖注入提供操作性”。

诀窍是创建自己的扩展的工作工厂,SimpleJobFactory然后您有机会初始化/注入工作的依赖关系,如下所示:

public class MyJobFactory extends SimpleJobFactory {
    private final MyComponent component;

    @Inject
    public MyJobFactory(MyComponent component) {
        this.component = component;
    }

    @Override
    public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
        final Job job = super.newJob(bundle, scheduler);
        if (job instanceof MyJob) {
            component.inject((MyJob) job);
        }
        return job;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您告诉调度程序使用作业工厂:

scheduler.setJobFactory(myJobFactory);
Run Code Online (Sandbox Code Playgroud)

在GitHub上查看完整代码