Spring-Quartz自定义注释与Spring集成

在之前的文章中,我们演示了如何在Spring容器中创建和配置带有批注的Quartz作业。我们使用一个类级别的注释来添加一些元数据到一个实现了Quartz Job的bean; 注释定义了作业的名称,组和它的cron表达式。后来,大部分代码专门用于处理该注释:查找bean,读取注释,创建JobDetailCronTrigger,应用它们的属性,并将它们传递给调度器。

如果你正在开发一个平均到大型的spring项目,你可能很快就会开始看到样板配置和代码,这些配置和代码可以通过将其封装在注释中进行重构; 该@QuartzJob注释是一个很好的例子。

在masetta中,我们尝试使用Polyforms项目来使用注释来实现DAO方法(通常由一些JPA查询的样板代码组成)。很快,我们发现它不像我们需要的那样可配置和可扩展,在处理命名查询参数和初始化顺序问题时存在问题(因为Polyforms如何使用方面来实现抽象方法)。此外,我们使用自定义注释并“手动”处理它们,但它们变得太多了……

我们想到的是spann。Spann是Spring框架的开源扩展,它允许使用注释来高级配置Spring Bean。为了窥视spann的一个特性,我将依赖我们  以前的文章  并实现类似的功能。我将使用spann来代替编码。正如你将会看到的,这个实现非常简短。

概观

该代码使用Spring的本地Quartz调度实现(如在Spring参考中所述)。Spring的MethodInvokingJobDetailFactoryBean用于创建一个将作业执行委托给另一个bean的方法的JobDetail bean。作为触发器,我使用Spring的CronTrigger实现。

要创建和配置JobDetailCronTrigger bean,我将使用spann的@BeanConfig注释创建方法级别的注释。

 

它包含一个包含所有需要的依赖关系坐标和功能测试用例的pom。

1.创建注释以配置MethodInvokingJobDetailFactoryBean


 

@BeanConfig注释创建和配置MethodInvokingJobDetailFactoryBean中使用QuartzJob的注释的属性(名称,组和并发)。

配置的bean通过“ quartzJob ”角色“附加”到带注释的方法。稍后将使用它来将JobDetail bean 注入到触发器。“附加”是一个内部spann概念。它允许通过指定工件(例如类或方法)和语义角色(此处为’quartzJob’)而不是按名称来引用bean。这使得注释组合成为spann最强大的功能,这也在这里展示。

wire属性使用从当前工件的元数据(本例中为MethodMetadata),ScanContext和Annotation使用给定工厂填充的值来设置targetObject和targetMethod属性。

2.创建一个cron触发器注释


 

我再次使用@BeanConfig注释,这次创建并配置一个CronTriggerBean

在明确的属性指示如何处理默认注解的属性值。如果显式为true,则忽略默认属性值。例如,的timeZone,misfireInstructionName和triggerListenerNames所述的性质CronTriggerBean将仅在相应的注解的属性值集合; 默认值将被默默忽略。

使用references属性,jobDetail属性设置为在步骤1中创建的bean:s​​pann将使用’ quartzJob ‘角色查找附加到注释方法的bean 。

请注意,timeZone注释属性类型是String,而CronTriggerBean的timeZone属性类型是TimeZone。该值由Spring本地处理,使用Spring的PropertyEditor工具透明地转换为TimeZone。你甚至可以使用Spring的$ {…}语法来进行表达式替换。

在检入代码包含第三注解创建间隔触发,稍后在本实施例中使用。

3.配置spann和spring的SchedulerFactoryBean

我们的applicationContext.xml非常简短:


 

如果你知道spring,那么在这里就不应该有任何魔法了:我配置了spring的组件扫描,spann扫描和SchedulerFactoryBean,如Spring引用中所描述的,只有在这里我让spring自动装载所有触发器bean到相应的属性,因此autowire =’byType’。

4.使用注释


 

这个bean是通过spring的@Component注解配置的。它的一个普通的Spring bean,以及任何Spring或aspect-annotation(@ Autowired@Resource,@ Transactional)将由Spring本地处理。

默认情况下,spann只处理类级别注释; @VisitMethods指示spann也访问这个类的方法并处理它们的注释(如果存在的话)。

新注释的使用非常简单:每个计划的方法都应该使用@QuartzJob(创建委托JobDetail)以及@Cron@Interval注释(此处未显示,但在svn中可用)注释以创建触发器。

这也演示了spann的注释组合,它允许注释细化和可插入:@QuartzJob可以用于配置Trigger bean的任何注释,而@Cron@Interval可以用于配置JobDetail bean的任何注释。

概要

Spann是Spring框架的开源扩展,允许使用注释进行高级bean配置。该代码演示了如何使用spann的@BeanConfig注释来创建使用注释的Quartz预定作业。

该示例使用spann的高级API,即在spann项目本身中实现的@BeanConfig注释。Spann的高级API包括其他允许方法替换的注释(用于在运行时实现抽象方法,在内部使用cglib),合成适配器创建和全面的JPA查询支持。

Spann与Spring的集成非常紧密:它创建了“简单的老春豆”,就像在XML或@Component注释中定义的那样。这使您可以利用Spring的所有bean特性:bean可以通过Spring的ApplicationContext获取,具有正常的bean生命周期,可以进行后处理(例如用于表达式替换),自动装配,使用方面拦截,通过JMX管理等上。您不需要黑客和变通办法,也不需要重新实现或复制和调整现有的弹簧代码。此外,您的样板代码更少,样板配置更少。

@BeanConfig和spann的其他注释一样灵活,有些用例并不包括在内。但是spann的低级API允许从头开始创建新的注释,使开发人员能够对bean定义的创建和配置进行细粒度的控制。您甚至可以使用spann通过实现您自己的MetadataVisitor来处理任何其他类的元数据,可以选择全部忽略注释。

原创于 【模棱博客】