向QuartzJobObject注入属性
本文关键字:属性 注入 QuartzJobObject | 更新日期: 2023-09-27 18:09:41
我认为我的QuartzJobObject
不能有任何DAO或其他spring管理的对象注入到它是正确的吗?
我希望我能做这样的事情(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,服务等。但我不明白。我该怎么做呢?
这就是我最终的结果,它工作得很好(希望对其他人有用)
了解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);
}
}
作业本身(检查DB中的记录,如果至少有 homanymenuitemsisok 记录,则一切正常)。注意:menuService是一个注入的spring管理对象,它本身有几个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>
您可以通过覆盖CreateJobInstance
的属性/构造函数注入到您的工作并注册新的JobFactory,而不是默认的。
在TriggerFiredBundle
中传递的信息为您提供了足够的信息,以便向上下文请求匹配的作业(基于约定)。bundle.JobDetail.JobType.Name
和bundle.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>
我不知道是否有什么问题,因为这是2008年开发的,我没有跟踪quartz.net的集成进度。