Java中的@Repeatable注解使用詳解
@Repeatable
@Repeatable注解是java8為了解決同一個注解不能重復在同一類/方法/屬性上使用的問題。
@Repeatable是jdk8中新增的注解,使用如Spring中的@ComponentScan注解。
在沒有@Repeatable注解的的注解中,在同一個地方使用相同的注解會報錯,有了此元注解注解的注解,就可以在同一個地方使用相同的注解。
舉例說明
舉一個比較貼近開發(fā)的例子,在spring/springboot我們引入資源文件可以使用注解@PropertySource
@PropertySource("classpath:sso.properties") public class Application { }
那要引入多個資源文件怎么辦,沒事,我把PropertySource中的value設置成String[]數組就行了
public @interface PropertySource { ... String[] value(); }
那么就能這么用
@PropertySource({"classpath:sso.properties","classpath:dubbo.properties","classpath:systemInfo.properties"}) public class Application { }
就spring引入配置文件來講,肯定是沒事問題的。但是如果注解中2個值存在依賴關系,那么這樣就不行了。比如下面這個
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Validate { /** * 業(yè)務類型 * @return */ String bizCode(); /** * 訂單類型 * @return */ int orderType(); }
上面的@validate注解,bizcode和orderType是一對一的關系,我希望可以添加如下的注解
@Validate(bizCode = "fruit",orderType = 1) @Validate(bizCode = "fruit",orderType = 2) @Validate(bizCode = "vegetable",orderType = 2) public class BizLogic2 { }
很抱歉在java8之前,這種方式不行,不過你可以這么做,新建一個如下的注解
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented public @interface Validates { Validate[] value(); }
然后對應代碼修改如下
@Validates(value = { @Validate(bizCode = "fruit",orderType = 1) @Validate(bizCode = "fruit",orderType = 2) @Validate(bizCode = "vegetable",orderType = 2) }) public class BizLogic2 { }
在java8的@Repeatable出來之后,我們在不改動@Validates的情況下,對@Validate進行修改,增加 @Repeatable(Validates.class)
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Repeatable(Validates.class) public @interface Validate { /** * 業(yè)務類型 * @return */ String bizCode(); /** * 訂單類型 * @return */ int orderType(); }
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented public @interface Validates { Validate[] value(); }
注意,一旦使用Repeatable注解指定了注解Validates,那么這個聚合注解默認約束value來存儲子注解,用其他的名字代替value均會編譯報錯
那么就可以在類上使用多個@Validate注解了。
@Validate(bizCode = "fruit",orderType = 1) @Validate(bizCode = "fruit",orderType = 2) @Validate(bizCode = "vegetable",orderType = 2) public class BizLogic2 { }
還有一點需要注意,我的@Validate是被@Component元注解標注,當多個@Validate語法糖轉換成@Validates之后,由于@Validates上沒@Component,導致我的bean加載不到spring容器中去
@Repeatable 原理
那么@Repeatable的原理是啥? 其實就是語法糖
對于下面的注解
@Repeatable(Persons.class) public @interface Person { String role() default ""; String name() default ""; }
public @interface Persons { Person[] value(); }
我們給下面這個類加上注解,重點關注這個類,打開這個編譯后的類(即這個java文件對應的class文件)
@Person(role = "警察",name = "小花") @Person(role = "小偷",name = "笑話") public class AnnotationTest { }
我們得到下面的代碼
@Persons({@Person( role = "警察", name = "小花" ), @Person( role = "小偷", name = "笑話" )}) public class AnnotationTest { public AnnotationTest() { } }
從這里可以看出的確就是語法糖。
問題來了 我們打開下面這個編譯后的類
@Person(role = "警察",name = "小花") public class AnnotationTest { }
得到的結果是這樣
@Person( role = "警察", name = "小花" ) public class AnnotationTest { public AnnotationTest() { } }
那這樣就存在問題了,我以為加了@Repeatable之后@Validate都會生成被語法糖@Validates包裹。
沒想到它居然這么智能,只有一個@Validate注解的時候居然不轉換。
所以使用多個@Validate的時候就會留坑,你需要兼容1個或多個的場景。
到此這篇關于Java中的@Repeatable注解使用詳解的文章就介紹到這了,更多相關@Repeatable注解使用內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
idea ssm項目java程序使用十六進制rxtx包向串口發(fā)送指令的方法
這篇文章主要介紹了idea ssm項目java程序向串口發(fā)送指令并且使用十六進制 rxtx包,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08springMVC向Controller傳值出現中文亂碼的解決方案
這篇文章主要介紹了springMVC向Controller傳值出現中文亂碼的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02java 注解annotation的使用以及反射如何獲取注解
這篇文章主要介紹了java 注解annotation的使用以及反射如何獲取注解的相關資料,需要的朋友可以參考下2017-01-01在Java的MyBatis框架中建立接口進行CRUD操作的方法
這篇文章主要介紹了在Java的MyBatis框架中建立接口進行CRUD操作的方法,CRUD是指在做計算處理時的增加(Create)、重新取得數據(Retrieve)、更新(Update)和刪除(Delete)幾個單詞的首字母簡寫,需要的朋友可以參考下2016-04-04多模塊項目引入SpringSecurity后一直報404的解決方案
這篇文章主要介紹了多模塊項目引入SpringSecurity后一直報404的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06