一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語(yǔ)言 - JAVA教程 - 創(chuàng)建自定義的Java注解類的方法

創(chuàng)建自定義的Java注解類的方法

2019-12-25 13:42goldensun JAVA教程

這篇文章主要介紹了創(chuàng)建自定義的Java注解類的方法,主要部分為創(chuàng)建一個(gè)帶有Java類型@interface的新類型,需要的朋友可以參考下

 如果你已經(jīng)在使用Java編程,并且也使用了任何像Spring和Hibernate這樣的流行框架,那么你應(yīng)該對(duì)注解的使用非常地熟悉。使用一個(gè)現(xiàn)有框架工作的時(shí)候,通常使用它的注解就夠了。但是,你是不是也有時(shí)候有要?jiǎng)?chuàng)建屬于你自己的注解的需求呢?

不久之前,我找到了一個(gè)自己創(chuàng)建一個(gè)注解的理由,那是一個(gè)涉及驗(yàn)證存儲(chǔ)在多種數(shù)據(jù)庫(kù)中的常用數(shù)據(jù)的項(xiàng)目。
場(chǎng)景描述

該業(yè)務(wù)有多種數(shù)據(jù)庫(kù)都存儲(chǔ)著相同的數(shù)據(jù),它們有各自不同的保持?jǐn)?shù)據(jù)更新的方法. 該業(yè)務(wù)曾計(jì)劃把所有這些數(shù)據(jù)都整合到一個(gè)主數(shù)據(jù)庫(kù)中,以減輕涉及到多種數(shù)據(jù)源所帶來(lái)的問(wèn)題的復(fù)雜性.


不過(guò)在項(xiàng)目開始之前,業(yè)務(wù)還需要知道數(shù)據(jù)距離可以同步還有多少差距,并做出任何必要的修正來(lái)使其可以進(jìn)行同步. 第一步需要?jiǎng)?chuàng)建一個(gè)展示那些數(shù)據(jù)多種數(shù)據(jù)庫(kù)的通用數(shù)據(jù)的報(bào)表,并對(duì)其值進(jìn)行驗(yàn)證, 對(duì)那些不符合條件的記錄進(jìn)行高亮顯示. 這里有一個(gè)對(duì)當(dāng)時(shí)需求的簡(jiǎn)短摘要:

  •     比對(duì)多種數(shù)據(jù)庫(kù)間公共部分的數(shù)據(jù),諸如客戶,公司或者目錄信息.
  •     默認(rèn)的值應(yīng)該根據(jù)值的類型匹配所有的數(shù)據(jù)庫(kù).
  •     對(duì)于某些字段,我們只想展示其值,而不要進(jìn)行任何數(shù)據(jù)比較.
  •     對(duì)于某些字段,我們只想要對(duì)比其值,并在指定的特定數(shù)據(jù)源上進(jìn)行數(shù)據(jù)驗(yàn)證.
  •     對(duì)于某些字段,我們可能想要做一些復(fù)雜的數(shù)據(jù)比較,可能會(huì)基于記錄內(nèi)的其它字段.
  •     對(duì)于某些字段,我們可能想要用一種特定格式對(duì)數(shù)據(jù)進(jìn)行格式化,比如錢幣數(shù)量 使用 $000,000.00 .
  •     報(bào)表應(yīng)該用MS Excel格式的,每一行都包含來(lái)自每個(gè)數(shù)據(jù)源的字段值. 任何不匹配數(shù)據(jù)驗(yàn)證規(guī)則的行都應(yīng)該用黃色高亮顯示.

注解

經(jīng)過(guò)一陣子對(duì)需求和一些想法的推敲之后,我決定使用注解來(lái)驅(qū)動(dòng)對(duì)于數(shù)據(jù)比對(duì)和報(bào)表處理的配置. 我們需要的東西得是簡(jiǎn)單,而高度靈活可擴(kuò)展的. 這些注解將會(huì)是字段級(jí)別的,而我就喜歡配置不會(huì)被隱藏在classpath某個(gè)地方的文件中. 如此,你就能夠直接查看同一個(gè)字段相關(guān)聯(lián)的注解,以便知曉它具體是如何進(jìn)行處理的.

在最簡(jiǎn)單的情況下,注解無(wú)非就是一個(gè)標(biāo)記,就只是提供信息而不會(huì)對(duì)代碼執(zhí)行的操作本身有直接影響的元數(shù)據(jù). 如果你一直在從事Java編程,那么現(xiàn)在你對(duì)它們的使用應(yīng)該相當(dāng)?shù)氖煜ち? 但是可能你從來(lái)沒(méi)有過(guò)創(chuàng)建屬于你自己的注解的需求. 為此,你需要?jiǎng)?chuàng)建一個(gè)帶有Java類型@interface的新類型,它將包含能指定元數(shù)據(jù)詳細(xì)信息的要素.

這里有一個(gè)來(lái)自這個(gè)項(xiàng)目的示例:
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ReconField {
 
  /**
   * Value indicates whether or not the values from the specified sources should be compared or will be used to display values or reference within a rule.
   *
   * @return The value if sources should be compared, defaults to true.
   */
  boolean compareSources() default true;
 
  /**
   * Value indicates the format that should be used to display the value in the report.
   *
   * @return The format specified, defaulting to native.
   */
  ReconDisplayFormat displayFormat() default ReconDisplayFormat.NATIVE;
 
  /**
   * Value indicates the ID value of the field used for matching source values up to the field.
   *
   * @return The ID of the field.
   */
  String id();
 
  /**
   * Value indicates the label that should be displayed in the report for the field.
   *
   * @return The label value specified, defaults to an empty string.
   */
  String label() default "";
 
  /**
   * Value that indicates the sources that should be compared for differences.
   *
   * @return The list of sources for comparison.
   */
  ReconSource[] sourcesToCompare() default {};
 
}

這是驅(qū)動(dòng)數(shù)據(jù)比對(duì)過(guò)程如何運(yùn)作的主要注解. 它包含的基本要素,可以滿足不同數(shù)據(jù)源間數(shù)據(jù)進(jìn)行比較的大部分需求. @ReconField 可以處理除更加復(fù)雜的比對(duì)之外,我們所期望的大多數(shù)需求, 而更加復(fù)雜的情況我們將會(huì)在稍后有所討論. 這些要素的大多數(shù)在代碼清單中一對(duì)一的注釋中都有介紹, 而需要指出的是,在我們的@ReconField上有幾個(gè)關(guān)鍵的注解.

    @Target – 這個(gè)注解可以讓你來(lái)指定你的注解應(yīng)該被用在那個(gè)java元素上. 可能的目標(biāo)類型是 ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER 和 TYPE. 在我們的 @ReconField 注解中他被指定到了 FIELD 級(jí)別.

    @Retention – 它可以讓你指定注解在何時(shí)生效. 可能的值有 CLASS, RUNTIME 和 SOURCE. 因?yàn)槲覀儗?huì)在運(yùn)行時(shí) RUNTIME 處理這個(gè)注解, 所以那就是我們需要設(shè)置的值.


這一數(shù)據(jù)驗(yàn)證過(guò)程將會(huì)為每一個(gè)數(shù)據(jù)庫(kù)運(yùn)行一次查詢,并且將結(jié)果映射到展示出針對(duì)特定業(yè)務(wù)記錄類型所有字段的實(shí)體bean中. 映射數(shù)據(jù)實(shí)體的每一個(gè)字段上的注解會(huì)告訴處理器如何為特定字段及在每個(gè)數(shù)據(jù)庫(kù)中找到的其值執(zhí)行數(shù)據(jù)比對(duì). 因此讓我們來(lái)看幾個(gè)示例來(lái)了解這些注解是如何被運(yùn)用于不同的數(shù)據(jù)比對(duì)配置的.

為了驗(yàn)證現(xiàn)有的值并同每個(gè)數(shù)據(jù)源中的只精確匹配,你只需要提供一個(gè)字段ID以及將會(huì)展示在報(bào)表上字段的標(biāo)記.

?
1
2
@ReconField(id = CUSTOMER_ID, label = "Customer ID")
private String customerId;

為了展示在每個(gè)數(shù)據(jù)源中找到的值,但不做任何數(shù)據(jù)比對(duì),你可能需要制定 compareSources 元素,并將其值設(shè)置為false.
 

?
1
2
@ReconField(id = NAME, label = "NAME", compareSources = false)
private String name;


為了驗(yàn)證在指定數(shù)據(jù)源中找到的值,而不是全部,你可能會(huì)使用到 elementsourcesToCompare. 使用這個(gè)東西會(huì)展示所有找到的值,但是只對(duì)在元素中列出的數(shù)據(jù)源中找到的值進(jìn)行比對(duì). 這樣就能處理有些不是在每一個(gè)數(shù)據(jù)源中都會(huì)存儲(chǔ)的數(shù)據(jù)場(chǎng)景了. ReconSource 是一個(gè)包含了可以用來(lái)進(jìn)行比對(duì)的數(shù)據(jù)源的枚舉類型.
 

?
1
2
@ReconField(id = PRIVATE_PLACEMENT_FLAG, label = "PRIVATE PLACEMENT FLAG", sourcesToCompare ={ ReconSource.LEGACY, ReconSource.PACE })
private String privatePlacementFlag;

現(xiàn)在我們已經(jīng)滿足了我們的基本需求,我們需要解決實(shí)現(xiàn)指定字段來(lái)進(jìn)行復(fù)雜數(shù)據(jù)比對(duì)能力的問(wèn)題. 為此,我們將創(chuàng)建第二個(gè)注解,來(lái)驅(qū)動(dòng)定制規(guī)則處理.
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ReconCustomRule {
 
/**
* Value indicates the parameters used to instantiate a custom rule processor, the default value is no parameters.
*
* @return The String[] of parameters to instantiate a custom rule processor.
*/
String[] params() default {};
 
/**
* Value indicates the class of the custom rule processor to be used in comparing the values from each source.
*
* @return The class of the custom rule processor.
*/
Class<?> processor() default DefaultReconRule.class;
 
}


同之前的注解非常類似,最大的不同在于 @ReconCustomRule 注解中我們指定了一個(gè)類,它可以在重建處理執(zhí)行時(shí)執(zhí)行數(shù)據(jù)比對(duì). 你可以只定義將會(huì)被用到的類,那樣你的處理器就可以實(shí)例化并初始化你所指定的類. 在這個(gè)注解中指定的類將需要實(shí)現(xiàn)一個(gè)通用的規(guī)則接口,它將會(huì)被規(guī)則處理器用來(lái)執(zhí)行規(guī)則.

現(xiàn)在讓我們來(lái)看看使用這個(gè)注解 的例子.

在本例中,我們使用了一個(gè)自定義的規(guī)則,它將會(huì)檢查股票交易所是不是 United States,如果是則跳過(guò)這條數(shù)據(jù). 為此,這條規(guī)則將需要檢查同一記錄中的 exchange country 字段.
 

?
1
2
3
@ReconField(id = STREET_CUSIP, label = "STREET CUSIP", compareSources = false)
@ReconCustomRule(processor = SkipNonUSExchangeComparisonRule.class)
private String streetCusip;

這里的示例我們?yōu)樽远x規(guī)則指定了一個(gè)參數(shù),這里它是一個(gè)包容量. 對(duì)于這種特殊的數(shù)據(jù)比對(duì),被比較的值不能偏離超過(guò)1000.通過(guò)使用指定了包容量的參數(shù),我們就可以使用不同的包容量將同一套自定義規(guī)則運(yùn)用到多個(gè)字段上. 唯一的缺點(diǎn)就是,由于注解的性質(zhì),這些參數(shù)都只能是靜態(tài)的,所以不能動(dòng)態(tài)的修改.
 

?
1
2
3
4
@ReconField(id = USD_MKT_CAP, label = "MARKET CAP USD", displayFormat = ReconDisplayFormat.NUMERIC_WHOLE, sourcesToCompare =
{ ReconSource.LEGACY, ReconSource.PACE, ReconSource.BOB_PRCM })
@ReconCustomRule(processor = ToleranceAmountRule.class, params = { "10000" })
private BigDecimal usdMktCap;

如你所見,我們只使用了幾個(gè)簡(jiǎn)單的注解,就設(shè)計(jì)出了一個(gè)具有相當(dāng)程度靈活性的面向多數(shù)據(jù)庫(kù)場(chǎng)景的數(shù)據(jù)驗(yàn)證報(bào)告功能. 在這個(gè)特殊情況下,注解驅(qū)動(dòng)了數(shù)據(jù)的比對(duì)過(guò)程,因此我們實(shí)際上就是使用了注解在找到的映射數(shù)據(jù)實(shí)體上進(jìn)行計(jì)算并直接使用它們進(jìn)行處理.

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品1024永久免费视频 | 亚洲 欧美 国产 综合首页 | 暖暖视频免费观看视频中国.韩剧 | 亚洲精品丝袜在线一区波多野结衣 | 日韩综合久久 | 色综合色狠狠天天久久婷婷基地 | 亚洲精品久久久WWW游戏好玩 | 色多多在线观看视频 | 我要看逼 | 欧美vpswindows动物 | xxxx在线视频 | 91麻豆国产精品91久久久 | xx18美女美国| 窝窝午夜精品一区二区 | ipx358cn出差被男上司在线 | 欧美日韩国产精品自在自线 | 亚洲国产午夜看片 | 高h辣文小说网 烧书阁 | 日本中出视频 | 香港论理午夜电影网 | 天天av天天翘天天综合网 | 色一情一区二区三区四区 | 亚洲国产精品一区二区久久 | 韩国美女被的免费视频 | 日本视频免费在线 | 荡娃艳妇有声小说 | 国内久久精品视频 | 性妲己 | 久久机热视频 这里只有精品首页 | boobsmilking流奶水 | 毛片大全免费看 | 无人区在线观看免费观看 | 国产麻豆麻豆 | 我与肥熟老妇的性事 | 91交换论坛 | 日本高清不卡一区久久精品 | 欧美sq | 变态np虐高h | 日本国产在线视频 | 亚洲黄色色图 | 欧美丝袜videohd|