2011-09-25 72 views
2

我是否認爲我的QuartzJobObject不能有任何注入DAO或其他Spring管理的對象?將屬性注入到QuartzJobObject中

希望我可以做這樣的事情(orderService是我想什麼注入):

<object name="checkPendingOrdersJob" type="Spring.Scheduling.Quartz.JobDetailObject, Spring.Scheduling.Quartz"> 
    <property name="JobType" value="Munch.ScheduledTasks.CheckPendingOrdersJob" /> 
    <!-- We can inject values through JobDataMap --> 
    <property name="JobDataAsMap"> 
    <dictionary> 
     <!--entry key="UserName" value="Alexandre" /--> 
    </dictionary>  
    </property> 
    <property name="orderService" ref="orderService"/> 
</object> 

...我知道不作,因爲它是類型的感覺。但是,我能夠以某種方式注入一些DAO,服務等。我無法弄清楚。我怎樣才能做到這一點?

回答

1

您可以通過過濾的 AdaptableJobFactory來執行屬性/構造函數注入您的工作,並註冊您的新JobFactory而不是默認的JobFactory。

傳遞給TriggerFiredBundle爲您提供了足夠的信息來詢問上下文匹配的工作(基於約定)。 bundle.JobDetail.JobType.Namebundle.JobDetail.JobType符合我的需要,所以早在2008年,我結束了與某事。像這樣(類派生形式AdaptableJobFactory並實現IApplicationContextAware獲得注入的情況下):

public class ContextAwareJobFactory : AdaptableJobFactory, IApplicationContextAware 
{ 
    private IApplicationContext m_Context; 

    public IApplicationContext ApplicationContext 
    { 
    set 
    { 
     m_Context = value; 
    } 
    } 

    protected override object CreateJobInstance(TriggerFiredBundle bundle) 
    { 
    return m_Context.GetObject(bundle.JobDetail.JobType.Name, bundle.JobDetail.JobType); 
    } 
} 

您需要使用下面的配置來註冊ContextAwareJobFactory:

<objects xmlns="http://www.springframework.net"> 
    <!-- Some simple dependency --> 
    <object name="SomeDependency" type="Namespace.SomeDependency, Assembly" /> 

    <!-- The scheduled job, gets the dependency. --> 
    <object name="ExampleJob" type="Namespace.ExampleJob, Assembly" singleton="false"> 
    <constructor-arg name="dependency" ref="SomeDependency"/> 
    </object> 

    <!-- The JobDetail is configured as usual. --> 
    <object name="ExampleJobDetail" type="Spring.Scheduling.Quartz.JobDetailObject, Spring.Scheduling.Quartz"> 
    <property name="JobType" value="Namespace.ExampleJob, Assembly"/>   
    </object> 

    <!-- The new JobFactory. --> 
    <object name="ContextAwareJobFactory" type="Namespace.ContextAwareJobFactory, Assembly" /> 

    <!-- Set the new JobFactory onto the scheduler factory. --> 
    <object id="quartzSchedulerFactory" type="Spring.Scheduling.Quartz.SchedulerFactoryObject, Spring.Scheduling.Quartz"> 
    <property name="JobFactory" ref="ContextAwareJobFactory"/> 
    </object>  
</objects> 

我不知道有某事。 ootb,因爲這是在2008年開發的,我沒有遵循quartz.net的整合進度。

+0

嘿感謝很多關於這一點,我會嘗試一下今晚回來後我的結果。乾杯! – Richard

+0

曾經玩過這個遊戲,但昨晚不能完成它的工作(雖然時間已晚)。放棄之後,我去了一個methodInvokingJob,它在我的一個服務上執行了一個方法,但後來我開始用我的spring上下文運行到循環引用。哎呀。今晚將繼續嘗試,雖然 – Richard

+0

我更新了帖子,希望現在更容易遵循。 – Andreas

2

這就是我結束了和它完美的作品(希望對大家有用別人)

招聘工廠意識到Spring的上下文

/// <summary> 
/// A custom job factory that is aware of the spring context 
/// </summary> 
public class ContextAwareJobFactory : AdaptableJobFactory, IApplicationContextAware 
{ 
    /// <summary> 
    /// The spring app context 
    /// </summary> 
    private IApplicationContext m_Context; 

    /// <summary> 
    /// Set the context 
    /// </summary> 
    public IApplicationContext ApplicationContext 
    { 
     set 
     { 
      m_Context = value; 
     } 
    } 

    /// <summary> 
    /// Overrides the default version and sets the context 
    /// </summary> 
    /// <param name="bundle"></param> 
    /// <returns></returns> 
    protected override object CreateJobInstance(TriggerFiredBundle bundle) 
    { 
     return m_Context.GetObject(bundle.JobDetail.JobType.Name, bundle.JobDetail.JobType); 
    } 
} 

作業本身 (檢查數據庫的記錄,如果有至少HomeManyMenuItemsIsOK他們,一切都很好)。注意:menuService是一個注入彈簧管理對象,它本身有幾個DAO)。 HowManyMenuItemsIsOK是通過作業數據映射傳入的靜態屬性。

public class CheckMenuIsHealthyJob : QuartzJobObject 
{ 
    private static readonly ILog log = LogManager.GetLogger(typeof(CheckMenuIsHealthyJob)); 

    public IMenuService menuService { get; set; } 
    public int HowManyMenuItemsIsOK { get; set; } 

    /// <summary> 
    /// Check how healthy the menu is by seeing how many menu items are stored in the database. If there 
    /// are more than 'HowManyMenuItemsIsOK' then we're ok. 
    /// </summary> 
    /// <param name="context"></param> 
    protected override void ExecuteInternal(JobExecutionContext context) 
    { 
     IList<MenuItem> items = menuService.GetAllMenuItems(); 
     if (items != null && items.Count >= HowManyMenuItemsIsOK) 
     { 
      log.Debug("There are " + items.Count + " menu items. Menu is healthy!"); 
     } 
     else 
     { 
      log.Warn("Menu needs some menu items adding!"); 
     } 

    } 
} 

最後Spring配置

<!-- Scheduled Services using Quartz --> 
    <!-- This section contains Quartz config that can be reused by all our Scheduled Tasks ----> 
    <!-- The Quartz scheduler factory --> 
    <object id="quartzSchedulerFactory" type="Spring.Scheduling.Quartz.SchedulerFactoryObject, Spring.Scheduling.Quartz"> 
    <!-- Tell Quartz to use our custom (context-aware) job factory --> 
    <property name="JobFactory" ref="contextAwareJobFactory"/> 

    <!-- Register the triggers --> 
    <property name="triggers"> 
     <list> 
     <ref object="frequentTrigger" /> 
     </list> 
    </property> 
    </object> 

    <!-- Funky new context-aware job factory --> 
    <object name="contextAwareJobFactory" type="Munch.Service.ScheduledTasks.ContextAwareJobFactory" /> 

    <!-- A trigger that fires every 10 seconds (can be reused by any jobs that want to fire every 10 seconds) --> 
    <object id="frequentTrigger" type="Spring.Scheduling.Quartz.CronTriggerObject, Spring.Scheduling.Quartz" lazy-init="true"> 
    <property name="jobDetail" ref="checkMenuIsHealthyJobDetail" /> 
    <property name="cronExpressionString" value="0/10 * * * * ?" /> 
    </object> 

    <!-- Now the job-specific stuff (two object definitions per job; 1) the job and 2) the job detail) --> 
    <!-- Configuration for the 'check menu is healthy job' --> 
    <!-- 1) The job --> 
    <object name="checkMenuIsHealthyJob" type="Munch.Service.ScheduledTasks.CheckMenuIsHealthyJob" singleton="false"> 
    <property name="menuService" ref="menuService"/> 
    </object> 

    <!-- 2) The job detail --> 
    <object name="checkMenuIsHealthyJobDetail" type="Spring.Scheduling.Quartz.JobDetailObject, Spring.Scheduling.Quartz"> 
    <property name="JobType" value="Munch.Service.ScheduledTasks.CheckMenuIsHealthyJob"/> 
    <property name="JobDataAsMap"> 
     <dictionary> 
     <entry key="HowManyMenuItemsIsOK" value="20" /> 
     </dictionary> 
    </property>  
    </object>