2015-07-28 56 views
2

我使用Dagger 2作爲我的DI框架,我正在爲它提供一個singleton類實例。如何使用Dagger在石英作業中注入依賴關係2

我也使用Quartz Scheduler來安排工作。有沒有辦法將singleton類注入到Quartz作業中?

匕首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."); 
    } 

} 

EDIT

我已經創建了一個MyJobScheduler類調​​用石英工作:

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); 

    } 
} 

EDIT 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."); 
    } 
} 

這是解決此問題的正確方法嗎?任何輸入將不勝感激。

+0

如何石英工作得到instantia特德? (這裏是'new MyJob()') –

+0

@ThorbjørnRavnAndersen查看編輯。這是一個非常基礎的Quartz實現。 –

回答

4

您的編輯2 DependencyResolver方法有點挫敗了使用Dagger注入依賴關係的全部原因,因爲您的工作獲得了來自單例提供者的依賴關係。 :-)它完全繞開了Dagger的好處,所以你可能只在源依賴本身上有一個單例,如:Messager messager = CustomMessager.getInstance()或類似的東西。

使用依賴注入的一個原因是協助進行單元測試,在這種情況下,您將失去在單元測試中模擬Messager實現的能力。

使用依賴注入在API doc for JobFactory提到石英工作的正確方法:「該接口可以使用到希望那些通過一些特殊的機制,讓他們的應用程序產生工作的情況下,如給在opertunity 依賴注入。「

關鍵是要創建一個擴展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); 

看到完整的代碼here on GitHub

+0

謝謝你的出色答案。 GitHub回購是一個非常好的接觸。 –

+0

我在GitHub代碼上有幾個問題:1.如果MyJobFactory未在模塊中提供(MyModule),MyJobScheduler會如何奇蹟般地注入MyJobFactory。 2.它不僅被注入也正在接收組件(MyComponent),它也以某種方式被注入而沒有任何明確的規定。這是否意味着我們可以在需要它的地方注入MyComponent來手動解決依賴關係。 3.我可以看到MyComponent.inject方法用於注入一個實例的依賴關係。這是否像一個標準的做法,或者更像是在這種特殊情況下的黑客行爲。 –

+0

1.有趣的觀察 - 是的,我認爲這是Dagger 2樣本中沒有廣泛展示或理解的東西 - 您不需要每個依賴項的提供者方法 - 如果它是第三方依賴項,則只需要一個模塊(沒有@Inject註釋),或者如果你需要初始化一個模塊,例如與活動的上下文...當你意識到這一點時,它減少了不必要的樣板! :) 2.是的,你可以注入組件本身,但這可能很容易被濫用。 3.在這種情況下,這是標準做法,因爲作業是在外部創建的,因此它是注入其字段的唯一方法 –

相關問題