通过SPANN方式将Spring&Quartz与自定义注释集成
如果您正在从事中等规模的大型Spring项目,那么您可能很快就会开始看到样板配置和代码,可以通过将其封装在批注中来进行重构。 @QuartzJob注释是一个很好的例子。
在masetta中,我们尝试使用Polyforms项目使用注释来实现DAO方法(该方法通常由围绕JPA查询的一些样板代码组成)。 很快,我们发现它并没有像我们所需要的那样可配置和可扩展,在处理命名查询参数和初始化顺序问题方面存在问题(因为Polyforms如何使用方面来实现抽象方法)。 此外,我们使用了自定义注释并“手动”处理了它们,但是它们的数量太多了……
我们想到的是span 。 Spann是spring框架的开源扩展,它允许使用注释对spring bean进行高级配置。 为了窥探spann的功能之一,我将依靠我们之前的文章并实现类似的功能。 我将使用spann而不是编码。 如您所见,实现非常简短。
总览
该代码使用Spring的本地Quartz调度实现(如spring参考中所述 )。 Spring的MethodInvokingJobDetailFactoryBean用于创建JobDetail bean,它将作业执行委托给另一个bean的方法。 作为触发器,我使用spring的CronTrigger实现。
为了创建和配置JobDetail和CronTrigger Bean,我将使用spann的@BeanConfig注释创建方法级别的注释。
代码
可以使用以下命令将示例代码作为跨项目的Maven项目检出:
svn co http://spann.googlecode.com/svn/trunk/spann-quartz-example
它包括一个带有所有必需的依赖项坐标的pom和一个功能测试用例。
1.创建注释以配置MethodInvokingJobDetailFactoryBean
package com.masetta.spann.quartzexample.annotations;import java.lang.annotation.*;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import com.masetta.spann.metadata.common.Artifact;
import com.masetta.spann.spring.base.beanconfig.*;
import com.masetta.spann.spring.base.beanconfig.factories.*;@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@BeanConfig(create=MethodInvokingJobDetailFactoryBean.class,attached=@Attached(role="quartzJob",scope=Artifact.METHOD),explicit=true,wire={@WireMeta(property="targetObject",scope=Artifact.CLASS,factory=BeanReferenceFactory.class),@WireMeta(property="targetMethod",scope=Artifact.METHOD,factory=MetadataNameFactory.class)})
public @interface QuartzJob {String name();String group();boolean concurrent() default true;}
该@BeanConfig注释创建和使用QuartzJob的注释的属性( 名称 , 组和并发 )配置一个MethodInvokingJobDetailFactoryBean中 。
已配置的bean通过“ quartzJob ”角色“附加”到带注释的方法。 稍后将使用它来将JobDetail bean注入触发器。 “连接”是内部跨度概念。 它允许通过指定工件(例如类或方法)和语义角色(此处为“ quartzJob”)而不是按名称来引用bean。 这将启用spanning最强大的功能注释合成 ,此处也将进行演示。
wire属性使用给定工厂使用从当前工件的元数据 (在本例中为MethodMetadata ), ScanContext和Annotation填充的值设置targetObject和targetMethod属性。
2.创建一个cron触发器注释
package com.masetta.spann.quartzexample.annotations;import java.lang.annotation.*;
import org.springframework.scheduling.quartz.CronTriggerBean;
import com.masetta.spann.metadata.common.Artifact;
import com.masetta.spann.spring.base.beanconfig.*;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@BeanConfig(create=CronTriggerBean.class,attached=@Attached(role="quartzTrigger",scope=Artifact.METHOD), explicit=true,references=@SpannReference(property="jobDetail",role="quartzJob", scope=Artifact.METHOD)
)
public @interface Cron {String cronExpression();String timeZone() default "";String misfireInstructionName() default "";String[] triggerListenerNames() default {}; }
再次使用@BeanConfig批注,这次创建和配置CronTriggerBean 。
显式属性指示如何处理默认的注释属性值。 当explicit为true时,默认属性值将被忽略。 例如, 时区 ,所述CronTriggerBean的misfireInstructionName和triggerListenerNames属性将仅在相应的注解的属性值集合; 默认值将被静默忽略。
使用references属性,将jobDetail属性设置为在步骤1中创建的bean:spann将查找附加到具有“ quartzJob ”角色的带注释方法的bean。
请注意, timeZone注释属性类型为String ,而CronTriggerBean的timeZone属性的类型为TimeZone 。 该值由Spring本地处理,使用Spring的PropertyEditor工具透明地转换为TimeZone 。 您甚至可以使用Spring的$ {…}语法进行表达式替换。
签入的代码包含用于创建间隔触发器的第三个注释,此示例稍后将使用它。
3.配置span和spring的SchedulerFactoryBean
我们的applicationContext.xml非常简短:
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:spann="http://os.masetta.com/spann/schema/spann-1.0"xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://os.masetta.com/spann/schema/spann-1.0 http://os.masetta.com/spann/schema/spann-1.0.xsd"><context:component-scan base-package="com.masetta.spann.quartzexample"/><spann:scan base-package="com.masetta.spann.quartzexample"/><bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" autowire=”byType”/></beans>
如果您知道spring,那么这里就没有什么魔术了:如spring参考中所述,我配置了spring的组件扫描,spann扫描和SchedulerFactoryBean ,仅在这里,我让spring将所有触发bean自动装配到相应的属性,因此autowire ='byType' 。
4.使用注释
package com.masetta.spann.quartzexample.test;import java.util.concurrent.atomic.AtomicInteger;import org.springframework.stereotype.Component;import com.masetta.spann.quartzexample.annotations.*;
import com.masetta.spann.spring.core.annotations.VisitMethods;@Component
@VisitMethods
public class Savana {private AtomicInteger newElemphants = new AtomicInteger();private AtomicInteger newZebras = new AtomicInteger();@QuartzJob(name="zebraBorn",group="savana")@Interval(repeatInterval=200)public void zebraBorn() {newZebras.incrementAndGet();}@QuartzJob(name="elephantBorn",group="savana")@Cron(cronExpression="0/2 * * ? * * *")public void elephantBorn() {newElemphants.incrementAndGet();}public int getNewZebras() {return newZebras.get();}public int getNewElephants() {return newElemphants.get();}}
该bean是通过spring的@Component注释配置的。 它是普通的Spring bean,并且任何Spring或方面注释(@ Autowired , @Resource ,@ Transactional )都将由Spring本地处理。
默认情况下,spann仅处理类级别的注释。 @VisitMethods指示spann也访问此类的方法并处理其注释(如果存在)。
新注释的使用很简单:每个计划的方法都应使用@QuartzJob (创建委托的JobDetail )和@Cron或@Interval注释(此处未显示,但在svn中可用)进行注释。 。
这也演示了spann的批注组合 ,该批注组合使批注可以粒度化和可插入: @QuartzJob可以与配置触发器 bean的任何注释一起使用,而@Cron和@Interval可以与配置JobDetail bean的任何注释一起使用。
摘要
Spann是Spring框架的开源扩展,它允许使用注释进行高级Bean配置。 该代码演示了spann的@BeanConfig批注如何使用批注创建Quartz计划的作业。
该示例使用spann的高级API(即@BeanConfig批注),该API在spann项目本身中实现。 Spann的高级API包括其他允许方法替换(用于在运行时实现抽象方法,内部使用cglib进行实现的方法),合成适配器创建和全面的JPA Query支持的注释。
Spann与spring的集成非常紧密:它创建了“普通的老式spring bean”,就像用XML或@Component批注定义的那样。 这使您可以利用spring的所有bean功能:可以通过spring的ApplicationContext检索bean,具有正常的bean生命周期,可以进行后处理(例如,用于表达式替换),自动装配,使用方面进行拦截,通过JMX管理等等。上。 您不需要黑客和变通办法,也不需要重新实现或复制和调整现有的Spring代码。 此外,您的样板代码更少,样板配置也更少。
与@BeanConfig和spann的其他注释一样灵活,在某些用例中它们没有涉及。 但是Span的低级API允许从头开始创建新的注释,从而为开发人员提供了对bean定义的创建和配置的精细控制。 您甚至可以通过实现自己的MetadataVisitor来使用spann处理任何其他类元数据 ,可以选择全部忽略注释。
参考: Spring&Quartz与Custom Annotation的集成,这是我们W4G合作伙伴 Ron Piterman的SPANN方法 。
相关文章 :
- Spring,Quartz和JavaMail集成教程
- 在运行时交换出Spring Bean配置
- Spring MVC3 Hibernate CRUD示例应用程序
- 使用Spring将POJO公开为JMX MBean
- Java教程和Android教程列表
翻译自: https://www.javacodegeeks.com/2011/10/spring-quartz-integration-with-custom_31.html
通过SPANN方式将Spring&Quartz与自定义注释集成相关推荐
- 使用SPANN方式将Spring&Quartz与自定义注释集成
在上一篇文章中 ,我们演示了如何在Spring容器中创建和配置带批注的Quartz作业. 我们使用了一个类级别的注释将一些元数据添加到实现Quartz Job的bean中. 批注定义了作业的名称,组及 ...
- spring aop 注释_使用Spring AOP,自定义注释和反射为您的应用程序审核基础结构
spring aop 注释 下一篇文章将演示如何使用Spring AOP和注释编写简单的审计. 审核机制将是干净,高效且易于维护的(和Kewwl!). 我将在用户管理系统上演示我的示例(假设您具有反射 ...
- 使用Spring AOP,自定义注释和反射为您的应用审核基础架构
下一篇文章将演示如何使用Spring AOP和注释编写简单的审计. 审核机制将是干净,高效且易于维护的(和Kewwl!). 我将在用户管理系统上演示我的示例(假设您对反射和AOP具有一般知识). 我们 ...
- Spring&Quartz集成自定义注释
我们知道Spring支持与Quartz框架集成. 但是到目前为止,Spring仅支持静态XML声明方法. 如果想了解如何将Spring与Quartz集成,可以参考Spring + Quartz + J ...
- Spring Quartz 框架结构概述(一)[转]
Spring Quartz 框架结构概述(一)[转] 标签:scheduler trigger jobdatamap 任务调度 quartz http://www.blogjava.ne ...
- Spring+Quartz定时任务调度
Spring+Quartz定时任务调度 2011/5 zqhxuyuan@gmail.com 参考文章: http://www.iteye.com/topic/399980 org.sprin ...
- java自定义标签 map_基于Spring MVC的自定义标签Tag
基于Spring MVC的自定义标签Tag 1.环境准备 本次小项目基于Spring MVC进行测试呈现,项目依赖的jar文件列表如下: 2.搭建SpringMVC Spring MVC环境最关键的两 ...
- Spring+Quartz 集群
转载 http://soulshard.iteye.com/blog/337886 单独的Quartz集群在http://unmi.blogjava.net/有Unmi翻译的Quartz Job Sc ...
- Spring+Quartz实现定时任务
Spring整合Quartz实现定时任务步骤很简单,大致需要经过如下几步:创建任务(Job).配置JobDetail.配置触发器(Trigger).配置SchedulerFactoryBean 首先使 ...
最新文章
- matlab fsolve()函数的使用。
- linux设置脚本开机启动centos7,centos7设置开机启动
- Python---常见问题
- 装逼神器,5 行 Python 代码 实现一键批量扣图,你get到了吗
- css多行文本溢出显示省略号(兼容ie)
- The C10K problem
- C语言PAT刷题 - 1024 科学计数法
- 国内主要安全产品及厂商
- 网站被攻击怎么办如何解决
- 控制面板设置java_win10系统打开java控制面板的具体技巧
- OSChina 周六乱弹 —— 飞机上飞离太阳那么近晒黑了不是很正常吗
- 0.靡不有初 鲜克有终
- 河北工程大学计算机考试题型,2019上半年河北工程大学计算机等级考试报名通知...
- [全网首发]一款好看的个人主页源码
- cs231 yacs配置文件工具的使用
- 告别“大小周”、回到二三线,程序员“内卷”时代终结?
- linux gzip 解压 函数,获取http的gzip内容,并解压
- 《乐高EV3机器人搭建与编程》一2.9 小结
- ios菜鸟之路:uiscrollview和pagecontrol的使用方法
- matlab校正系统使相角裕度不小于45,4验算已校正系统的相角裕度.PPT
热门文章
- 英语不会读怎么办?它来教你……
- mybatis中,collection配置后查询只显示一条记录
- 索引---B+Tree
- jdk 流合并_JDK 12,合并的收集器和命名的挑战
- jersey 入门示例_Jersey Web Service Hello World Java示例
- java分布式系统开发_从微服务到分布式系统-Java开发人员生存指南
- dynamodb容器使用_使用DynamoDB映射器将DynamoDB项目映射到对象
- java向后兼容吗_Java向后不兼容历史的观察
- javafx swing_Swing应用程序中的JavaFX 8 DatePicker
- 子模板继承父模板示例_模板设计模式示例