Scala:创建一个通用的Quartz Job类

时间:2012-05-07 12:37:45

标签: scala quartz-scheduler

我们使用quartz(java API)进行作业调度。这很好用。现在我试图用它来概括一些事情。 quartz api需要一个作业类作为参数来扩展Job接口。这使得通过构造函数传递参数变得不可能。

我们有一组作业都应该做同样的事情,执行检查,如果是,则调用一个动作,例如:

class SimpleJob extends Job {

def execute(context: JobExecutionContext) {
  val check = classOf[SimpleCheck].asInstanceOf[Class[Check]].newInstance()
  val result = check.execute(context.getJobDetail.getJobDataMap)

  if (result.shouldInvokeAction) {
    Action(result).execute
  }
}

然后通过调用:

实例化石英作业
newJob(classOf[SimpleJob]).with...

这很有效。

目标是将此逻辑重用于不同类型的检查 问题:我是否可以使用scala类型系统,我可以使用一个类型的JobClass,可以重复使用它来执行Check的任何子类?

我提出了以下解决方案:

class GenericJobRule[J <: Check](implicit m: Manifest[J]) extends Job {

  def execute(context: JobExecutionContext) {
    val check = m.erasure.newInstance().asInstanceOf[J]
    val result = check.execute(context.getJobDetail.getJobDataMap)

    if (result.shouldInvokeAction) {
      Action(result).execute
    }
  }
}

现在可以像这样实例化作业:

newJob(classOf[GenericJobRule[PerformanceCheck]])

这是有效的,但我认为实例化和转换类型绕过了类型检查的整个想法。有没有更好的方法来做到这一点?也许我们应该重新考虑我们的设计......

谢谢,艾伯特

1 个答案:

答案 0 :(得分:3)

也许一种可能性是使用类型类。我试图实现它(简化了一些事情),缺点是 特定作业规则始终必须实现doCheck方法(有关类型类的更多信息,请参阅herehere):

[编辑] :用特质替换抽象类。不再需要构造函数参数。

[EDIT2] :忘记类型类(在本例中)。现在变得更简单了。每张支票只是一个特质和一个实施类。你觉得怎么样?

trait GenericJobRule[J <: Check] extends Job {

  val genericCheck: J

  def execute(context: JobExecutionContext) {
    val result = genericCheck.execute(context.getJobDataMap)

    if (result.shouldInvokeAction) {
      Action(result).execute
    }
  }  
}

class JobRule1 extends GenericJobRule[SimpleCheck] {
  override val genericCheck = new SimpleCheck
}

现在可以像这样实例化作业:

newJob(classOf[JobRule1])

[EDIT3] :如果GenericJobRule是一个抽象类,这是另一种可能性:

abstract class GenericJobRule[J <: Check] extends Job {

  val genericCheck: J

  def execute(context: JobExecutionContext) {
    val result = genericCheck.execute(context.getJobDataMap)

    if (result.shouldInvokeAction) {
      Action(result).execute
    }
  }  
}

然后您可以动态创建特定的作业规则:

val myJobRule = new GenericJobRule[SimpleCheck] { override val genericCheck = new SimpleCheck }