通过SPANN方式将Spring&Quartz与自定义注释集成

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

如果您正在从事中等规模的大型Spring项目,那么您可能很快就会开始看到样板配置和代码,可以通过将其封装在批注中来进行重构。 @QuartzJob注释是一个很好的例子。

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

我们想到的是span 。 Spann是spring框架的开源扩展,它允许使用注释对spring bean进行高级配置。 为了窥探spann的功能之一,我将依靠我们之前的文章并实现类似的功能。 我将使用spann而不是编码。 如您所见,实现非常简短。

总览

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

为了创建和配置JobDetailCronTrigger 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填充的值设置targetObjecttargetMethod属性。

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时,默认属性值将被忽略。 例如, 时区 ,所述CronTriggerBeanmisfireInstructionNametriggerListenerNames属性将仅在相应的注解的属性值集合; 默认值将被静默忽略。

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

请注意, timeZone注释属性类型为String ,而CronTriggerBeantimeZone属性的类型为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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357778.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux学习之常用技巧

▌基础 学习 Bash 。你可以man bash来看看bash的东西&#xff0c;并不复杂也并不长。你用别的shell也行&#xff0c;但是bash是很强大的并且也是系统默认的。&#xff08;学习zsh或tsch只会让你在很多情况下受到限制&#xff09; 学习 vim 。在Linux下&#xff0c;基本没有什么…

java开发一个完整的秒杀与竞价网上商城

导读:网络商城近年来非常火热的一种经营方式,与现实生活中的商店的差别是利用电子商务的一些手段,从而沟通消费者与商家进行商品买卖的虚拟商店,减少买家卖家间的多层环节,减少运输的成本以及层层代理过程中的差价,这就有巨大的价格优势从而带来巨大的发展空间。网络商城…

precede和previous_Previous Analyses of Hungarian Phrase Structure

摘要&#xff1a;The most obvious empirical basis of the establishment of phrase structure rules is the observation of word order phenomena. Since in a large set of Hungarian sentences any permutation of the major constituents is grammatical, the conclusion…

判断存储过程是否存在某个参数名

select * from syscolumns where id (select id from sysobjects where name存储过程名) select * from syscolumns where id object_id(存储过程名) and name参数名 以上只是拿出参数列表&#xff0c;还要在WHERE 后加 NAMEHEHE 你想查的字段名。转载于:https://www.cnblogs.c…

罐中研讨会:设置JBoss BPM Suite全天研讨会

是否在寻找一种简单的方法来宣传&#xff0c;展示或演示JBoss业务流程管理套件&#xff08;BPM Suite&#xff09;产品的入门难度&#xff1f; 别无所求&#xff0c;因为我们召集了这个研讨会&#xff0c;因此您可以围绕JBoss BPM Suite构建一个晚上&#xff0c;半天或全天的…

java实现一个电子书下载系统

导读:电子书代表人们所阅读的数字化出版物, 从而区别于以纸张为载体的传统出版物, 电子书是利用计算机技术将一定的文字、图片、声音、影像等信息, 通过数码方式记录在以光、电、磁为介质的设备中, 借助于特定的设备来读取、复制、传输,已经为人们所熟悉。 众所周知,自20世…

常用FTP命令 1. 连接ftp服务器

1. 连接ftp服务器格式&#xff1a;ftp [hostname| ip-address]a)在linux命令行下输入&#xff1a; ftp 192.168.1.1b)服务器询问你用户名和密码&#xff0c;分别输入用户名和相应密码&#xff0c;待认证通过即可。 2. 下载文件 下载文件通常用get和mget这两条命令。a) get 格式…

java实现影视创作论坛

导读:随着时代的发展,互联网的出现,给传统影视行业带来的最大便利就是,方便了影视从业人员以及爱好者的交流和互动,而为用户提供一个书写影评,阅读影评以及回复影评的平台,以影评为载体来使用户感受影评、解读影评的是互联网在传统影视行业下应运而生的产物。 所谓的影视…

java 编码 js解码_js和java中URI的编码和解码

js中对文字进行编码主要有三个函数&#xff1a;escape&#xff0c;encodeURI&#xff0c;encodeURIComponent&#xff1b;对应解码为&#xff1a;unescape&#xff0c;decodeURI&#xff0c;decodeURIComponent这里不在说基本概念(基本概念可以参考w3cohool&#xff0c;里面叙述…

一文教你使用java开发一款推箱子游戏

导读&#xff1a;社会在进步&#xff0c;人们生活质量也在日益提高。高强度的压力也接踵而来。社会中急需出现新的有效方式来缓解人们的压力。此次设计符合了社会需求&#xff0c;Java推箱子游戏可以让人们在闲暇之余&#xff0c;体验游戏的乐趣。具有操作简单,易于上手的特点。…

java序列化深克隆_克隆可序列化和不可序列化的Java对象

java序列化深克隆开发人员经常依靠3d方库来避免重新发明轮子&#xff0c;尤其是在Java世界中&#xff0c;Apache和Spring这样的项目如此盛行。 在处理这些框架时&#xff0c;我们通常很少或根本无法控制其类的行为。 这有时会导致问题。 例如&#xff0c;如果您想深克隆一个不提…

ukt机器人_doc/readme/feishu.md · 贫道法号-乱来/PrometheusAlert - Gitee.com

PrometheusAlert全家桶飞书配置说明-----------------飞书机器人目前支持V1和V2两个版本&#xff0c;区别在于地址的不同V1地址&#xff1a;https://open.feishu.cn/open-apis/bot/hook​/​xxxxxxxxxxxxxxxxxxV2地址&#xff1a;https://open.feishu.cn/open-apis/bot/v2/hook…

uiautomator的坑和AAPT命令方式启动一个应用程序

最近在使用UIautomator完成公司的一个主流程的自动化&#xff0c;因为不适用H5和IOS所以会放弃这个工具的使用&#xff0c;现在记录在使用uiautomator的一些问题&#xff1a; 案列1&#xff1a;使用命令去启动要运用的apk包 使用命令方式启动&#xff0c;可以使用SDK中自带的aa…

一文教你用java实现即时通讯软件的设计(附下载源码)

导读&#xff1a;即时通讯软件即所谓的聊天工具&#xff0c;其主要用途是用于文字信息的传递与文件传输。使用eclipse作为即时通讯软件的开发工具&#xff0c;使用Socket建立通讯渠道&#xff0c;多线程实现多台计算机同时进行信息的传递&#xff0c;swing技术等进行实际开发相…

在Python,Java和Kotlin中标记参数和重载

在多种语言之间跳来跳去可以帮助您注意到不同语言的习惯用法和最佳做法之间的某些差异。 比较有趣的差异之一与一个函数执行多项操作有关。 Python 我们先来看一下Python。 Python实际上无法重载&#xff0c;因为用相同的名称定义一个新的函数/方法只会覆盖前一个函数/方法。 …

vue 扫码页面限制区域_Vue.js 单页面多路由区域操作的实例详解

单页面多路由区域操作在一个页面中有两个及以上的区域&#xff0c;需要通过设置路由的index.js&#xff0c;来操作这些区域的内容app.vue 中设置&#xff1a;index.js中设置&#xff1a;import vue from vueimport router from vue-routerimport hello from /components/helloi…

Divide and conquer:Drying(POJ 3104)

烘干衣服 题目大意&#xff1a;主人公有一个烘干机&#xff0c;但是一次只能烘干一件衣服&#xff0c;每分钟失水k个单位的水量&#xff0c;自然烘干每分钟失水1个单位的水量&#xff08;在烘干机不算自然烘干的那一个单位的水量&#xff09;&#xff0c;问你最少需要多长时间烘…

c#string倒数第二位插入字符_c#string倒数第二位插入字符_C#利用String类的IndexOf、LastIndexOf、...

一、String.IndexOfString.IndexOf 方法 (Char, Int32, Int32)报告指定字符在此实例中的第一个匹配项的索引(从0开始)。搜索从指定字符位置开始&#xff0c;并检查指定数量的字符位置。String.IndexOf(value, startIndex, count)参数value&#xff1a;要查找的 Unicode 字符。s…

使用所学的javaWeb知识,实现一个小型的记账管理系统

导读:控制过度消费通过记账,你会很清楚地知道自己的钱都用来做了什么,关于每分钱的去处心中都明明白白, 哪些是必要的开销,哪些是非理性的、应该避免的花费,分别占有多大的比例。有专家统计,个人 或者家庭的年节余比例要达到收人的40%才是正常的。参照这样的比例,对你找…

java小细节_为什么我喜欢Java的细节

java小细节他们说&#xff0c;Java太冗长了。 您可以找到Hello World程序的比较&#xff0c;这些程序在ruby中使用2行&#xff0c;在Java中使用10行&#xff0c;而要读取文件&#xff0c;您需要使用Java 20行和php中1行。 尽管示例经常被夸大&#xff08;例如&#xff0c;计算导…