在我的Grails应用程序中,我安装了Quartz插件。我希望拦截对每个Quartz作业类的execute方法的调用,以便在调用execute方法之前执行一些操作(类似于建议前的AOP )。
目前,我正试图从另一个插件的doWithDynamicMethods闭包中执行此截取操作,如下所示:
def doWithDynamicMethods = { ctx ->
// get all the job classes
application.getArtefacts("Job").each { klass ->
MetaClass jobMetaClass = klass.clazz.metaClass
// intercept the methods of the job classes
jobMetaClass.invokeMethod = { String name, Object args ->
// do something before invoking the called method
if (name == "execute") {
println "this should happen before execute()"
}
// now call the method that was originally invoked
def validMethod = jobMetaClass.getMetaMethod(name, args)
if (validMethod != null) {
validMethod.invoke(delegate, args)
} else {
jobMetaClass.invokeMissingMethod(delegate, name, args)
}
}
}
}所以,如果是这样的工作,比如
class TestJob {
static triggers = {
simple repeatInterval: 5000l // execute job once in 5 seconds
}
def execute() {
"execute called"
}
}它应印刷:
这种情况应在执行()之前发生。 执行调用
但是,我尝试的方法拦截似乎没有效果,相反,它只是打印:
执行调用
也许问题的原因是这个Groovy错误?尽管Job没有显式地实现org.quartz.Job接口,但我怀疑(由于某些Groovy ),它们是这个接口的实例。
如果这个错误确实是造成我的问题的原因,那么我还有什么办法可以“在方法拦截之前”呢?
发布于 2013-05-30 20:25:53
因为所有的作业类都是Spring,所以可以使用Spring解决这个问题。定义如下方面(调整切入点定义,使其只匹配您的作业类,我假设它们都在一个名为org.example.job的包中,并有一个以Job结尾的类名)。
@Aspect
class JobExecutionAspect {
@Pointcut("execution(public * org.example.job.*Job.execute(..))")
public void executeMethods() {}
@Around("executeMethods()")
def interceptJobExecuteMethod(ProceedingJoinPoint jp) {
// do your stuff that should happen before execute() here, if you need access
// to the job object call jp.getTarget()
// now call the job's execute() method
jp.proceed()
}
}您需要将这个方面注册为Spring (不管您给bean取了什么名称)。
发布于 2013-05-30 20:33:11
您可以在应用程序中注册自定义JobListener,以便在触发execute()之前处理逻辑。你可以用这样的方法:-
public class MyJobListener implements JobListener {
public void jobToBeExecuted(JobExecutionContext context) {
println "Before calling Execute"
}
public void jobWasExecuted(JobExecutionContext context,
JobExecutionException jobException) {}
public void jobExecutionVetoed(JobExecutionContext context) {}
}在引导程序中将自定义的作业侦听器注册到Quartz Scheduler:-
Scheduler scheduler = ctx.getBean("quartzScheduler") //ctx being application context
scheduler.getListenerManager().addJobListener(myJobListener, allJobs()):-
beans = {
myJobListener(MyJobListener)
}发布于 2013-05-30 19:46:15
你不可能得到那样的工种。如果您引用Quartz插件,您可以通过调用jobClasses获得它们:
application.jobClasses.each {GrailsJobClass tc -> ... }请参阅https://github.com/nebolsin/grails-quartz/blob/master/QuartzGrailsPlugin.groovy
如果您实际查看,您可以看到他们几乎是在做您想要取得的成就,而不需要使用aop或其他任何东西。
https://stackoverflow.com/questions/16787048
复制相似问题