2011-09-25 68 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>