繁体   English   中英

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

[英]How to inject dependency in a Quartz job using Dagger 2

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

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

Dagger 2模块:

@Module
public class MyModule {

    @Provides
    @Singleton
            Messager provideMessager() {

        return new CustomMessager();
    }
}

匕首2组件:

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

    Messager messager();
}

石英作业:

public class MyJob implements Job {

    // @Inject
    Messager messager;

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

        messager.sendMessage("Hello.");
    }

}

编辑

我创建了一个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);

    }
}

编辑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();
    }
}

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

DependencyResolver.initialize();

MyComponent myComponent = DependencyResolver.getMyComponent();

我在MyJob类中使用了DependencyResolver来获取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.");
    }
}

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

您的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;
    }
}

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

scheduler.setJobFactory(myJobFactory);

在GitHub上查看完整代码

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM