創立自界說的Java注解類的辦法。本站提示廣大學習愛好者:(創立自界說的Java注解類的辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是創立自界說的Java注解類的辦法正文
假如你曾經在應用Java編程,而且也應用了任何像Spring和Hibernate如許的風行框架,那末你應當對注解的應用異常地熟習。應用一個現有框架任務的時刻,平日應用它的注解就夠了。然則,你是否是也有時刻有要創立屬於你本身的注解的需求呢?
不久之前,我找到了一個本身創立一個注解的來由,那是一個觸及驗證存儲在多種數據庫中的經常使用數據的項目。
場景描寫
該營業有多種數據庫都存儲著雷同的數據,它們有各自分歧的堅持數據更新的辦法. 該營業曾籌劃把一切這些數據都整合到一個主數據庫中,以加重觸及到多種數據源所帶來的成績的龐雜性.
不外在項目開端之前,營業還須要曉得數據間隔可以同步還有若干差距,並做出任何須要的修改來使其可以停止同步. 第一步須要創立一個展現那些數據多種數據庫的通用數據的報表,並對其值停止驗證, 對那些不相符前提的記載停止高亮顯示. 這裡有一個對其時需求的冗長摘要:
注解
經由一陣子對需乞降一些設法主意的斟酌以後,我決議應用注解來驅動關於數據比對和報表處置的設置裝備擺設. 我們須要的器械得是簡略,而高度靈巧可擴大的. 這些注解將會是字段級其余,而我就愛好設置裝備擺設不會被隱蔽在classpath某個處所的文件中. 如斯,你就可以夠直接檢查統一個字段相干聯的注解,以便知曉它詳細是若何停止處置的.
在最簡略的情形下,注解不過就是一個標志,就只是供給信息而不會對代碼履行的操作自己有直接影響的元數據. 假如你一向在從事Java編程,那末如今你對它們的應用應當相當的熟習了, 然則能夠你歷來沒有過創立屬於你本身的注解的需求. 為此,你須要創立一個帶有Java類型@interface的新類型,它將包括能指定元數據具體信息的要素.
這裡有一個來自這個項目標示例:
@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 {}; }
這是驅動數據比對進程若何運作的重要注解. 它包括的根本要素,可以知足分歧數據源間數據停止比擬的年夜部門需求. @ReconField 可以處置除加倍龐雜的比對以外,我們所希冀的年夜多半需求, 而加倍龐雜的情形我們將會在稍後有所評論辯論. 這些要素的年夜多半在代碼清單中一對一的正文中都有引見, 而須要指出的是,在我們的@ReconField上有幾個症結的注解.
@Target – 這個注解可讓你來指定你的注解應當被用在誰人java元素上. 能夠的目的類型是 ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER 和 TYPE. 在我們的 @ReconField 注解中他被指定到了 FIELD 級別.
@Retention – 它可讓你指定注解在什麼時候失效. 能夠的值有 CLASS, RUNTIME 和 SOURCE. 由於我們將會在運轉時 RUNTIME 處置這個注解, 所以那就是我們須要設置的值.
這一數據驗證進程將會為每個數據庫運轉一次查詢,而且將成果映照到展現出針對特定營業記載類型一切字段的實體bean中. 映照數據實體的每個字段上的注解會告知處置器若何為特定字段及在每一個數據庫中找到的其值履行數據比對. 是以讓我們來看幾個示例來懂得這些注解是若何被應用於分歧的數據比對設置裝備擺設的.
為了驗證現有的值並同每一個數據源中的只准確婚配,你只須要供給一個字段ID和將會展現在報表上字段的標志.
@ReconField(id = CUSTOMER_ID, label = "Customer ID") private String customerId;
為了展現在每一個數據源中找到的值,但不做任何數據比對,你能夠須要制訂 compareSources 元素,並將其值設置為false.
@ReconField(id = NAME, label = "NAME", compareSources = false) private String name;
為了驗證在指定命據源中找到的值,而不是全體,你能夠會應用到 elementsourcesToCompare. 應用這個器械會展現一切找到的值,然則只對在元素中列出的數據源中找到的值停止比對. 如許就可以處置有些不是在每個數據源中都邑存儲的數據場景了. ReconSource 是一個包括了可以用來停止比對的數據源的列舉類型.
@ReconField(id = PRIVATE_PLACEMENT_FLAG, label = "PRIVATE PLACEMENT FLAG", sourcesToCompare ={ ReconSource.LEGACY, ReconSource.PACE }) private String privatePlacementFlag;
如今我們曾經知足了我們的根本需求,我們須要處理完成指定字段來停止龐雜數據比對才能的成績. 為此,我們將創立第二個注解,來驅動定制規矩處置.
@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 注解中我們指定了一個類,它可以在重建處置履行時履行數據比對. 你可以只界說將會被用到的類,那樣你的處置器便可以實例化並初始化你所指定的類. 在這個注解中指定的類將須要完成一個通用的規矩接口,它將會被規矩處置器用來履行規矩.
如今讓我們來看看應用這個注解 的例子.
在本例中,我們應用了一個自界說的規矩,它將會檢討股票生意業務所是否是 United States,假如是則跳過這條數據. 為此,這條規矩將須要檢討統一記載中的 exchange country 字段.
@ReconField(id = STREET_CUSIP, label = "STREET CUSIP", compareSources = false) @ReconCustomRule(processor = SkipNonUSExchangeComparisonRule.class) private String streetCusip;
這裡的示例我們為自界說規矩指定了一個參數,這裡它是一個包涵量. 關於這類特別的數據比對,被比擬的值不克不及偏離跨越1000.經由過程應用指定了包涵量的參數,我們便可以應用分歧的包涵量將統一套自界說規矩應用到多個字段上. 獨一的缺陷就是,因為注解的性質,這些參數都只能是靜態的,所以不克不及靜態的修正.
@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;
如你所見,我們只應用了幾個簡略的注解,就設計出了一個具有相當水平靈巧性的面向多半據庫場景的數據驗證申報功效. 在這個特別情形下,注解驅動了數據的比對進程,是以我們現實上就是應用了注解在找到的映照數據實體長進行盤算並直接應用它們停止處置.