Java中的@Repeatable注解使用詳解
@Repeatable
@Repeatable注解是java8為了解決同一個注解不能重復(fù)在同一類/方法/屬性上使用的問題。
@Repeatable是jdk8中新增的注解,使用如Spring中的@ComponentScan注解。
在沒有@Repeatable注解的的注解中,在同一個地方使用相同的注解會報(bào)錯,有了此元注解注解的注解,就可以在同一個地方使用相同的注解。
舉例說明
舉一個比較貼近開發(fā)的例子,在spring/springboot我們引入資源文件可以使用注解@PropertySource
@PropertySource("classpath:sso.properties")
public class Application {
}那要引入多個資源文件怎么辦,沒事,我把PropertySource中的value設(shè)置成String[]數(shù)組就行了
public @interface PropertySource {
...
String[] value();
}
那么就能這么用
@PropertySource({"classpath:sso.properties","classpath:dubbo.properties","classpath:systemInfo.properties"})
public class Application {
}
就spring引入配置文件來講,肯定是沒事問題的。但是如果注解中2個值存在依賴關(guān)系,那么這樣就不行了。比如下面這個
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Validate {
/**
* 業(yè)務(wù)類型
* @return
*/
String bizCode();
/**
* 訂單類型
* @return
*/
int orderType();
}
上面的@validate注解,bizcode和orderType是一對一的關(guān)系,我希望可以添加如下的注解
@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();
}
然后對應(yīng)代碼修改如下
@Validates(value = {
@Validate(bizCode = "fruit",orderType = 1)
@Validate(bizCode = "fruit",orderType = 2)
@Validate(bizCode = "vegetable",orderType = 2)
})
public class BizLogic2 {
}
在java8的@Repeatable出來之后,我們在不改動@Validates的情況下,對@Validate進(jìn)行修改,增加 @Repeatable(Validates.class)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Repeatable(Validates.class)
public @interface Validate {
/**
* 業(yè)務(wù)類型
* @return
*/
String bizCode();
/**
* 訂單類型
* @return
*/
int orderType();
}@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface Validates {
Validate[] value();
}
注意,一旦使用Repeatable注解指定了注解Validates,那么這個聚合注解默認(rèn)約束value來存儲子注解,用其他的名字代替value均會編譯報(bào)錯
那么就可以在類上使用多個@Validate注解了。
@Validate(bizCode = "fruit",orderType = 1)
@Validate(bizCode = "fruit",orderType = 2)
@Validate(bizCode = "vegetable",orderType = 2)
public class BizLogic2 {
}
還有一點(diǎn)需要注意,我的@Validate是被@Component元注解標(biāo)注,當(dāng)多個@Validate語法糖轉(zhuǎn)換成@Validates之后,由于@Validates上沒@Component,導(dǎo)致我的bean加載不到spring容器中去
@Repeatable 原理
那么@Repeatable的原理是啥? 其實(shí)就是語法糖
對于下面的注解
@Repeatable(Persons.class)
public @interface Person {
String role() default "";
String name() default "";
}
public @interface Persons {
Person[] value();
}
我們給下面這個類加上注解,重點(diǎn)關(guān)注這個類,打開這個編譯后的類(即這個java文件對應(yīng)的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 {
}
得到的結(jié)果是這樣
@Person(
role = "警察",
name = "小花"
)
public class AnnotationTest {
public AnnotationTest() {
}
}
那這樣就存在問題了,我以為加了@Repeatable之后@Validate都會生成被語法糖@Validates包裹。
沒想到它居然這么智能,只有一個@Validate注解的時(shí)候居然不轉(zhuǎn)換。
所以使用多個@Validate的時(shí)候就會留坑,你需要兼容1個或多個的場景。
到此這篇關(guān)于Java中的@Repeatable注解使用詳解的文章就介紹到這了,更多相關(guān)@Repeatable注解使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot集成JWT之雙重token的實(shí)現(xiàn)
本文主要介紹了springboot集成JWT之雙重token的實(shí)現(xiàn),前端使用accessToken進(jìn)行登錄和驗(yàn)證,后端使用refreshToken定期更新accessToken,具有一定的參考價(jià)值,感興趣的可以了解一下2025-03-03
Java獲取客戶端真實(shí)IP地址經(jīng)典寫法與Lambda寫法對比示例代碼
在網(wǎng)絡(luò)編程中,獲取客戶端的IP地址和端口地址是非常常見的需求,這篇文章主要介紹了Java獲取客戶端真實(shí)IP地址經(jīng)典寫法與Lambda寫法對比的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2026-05-05
吊打Java面試官之Lambda表達(dá)式 Stream API
這篇文章主要介紹了吊打Java之jdk8的新特性包括Lambda表達(dá)式、函數(shù)式接口、Stream API全面刨析,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09
快速解決commons-fileupload組件無法處理自定義head信息的bug
問題在于fileupload組件解析完自定義的head節(jié)點(diǎn)后,卻忘記傳遞到FileItemStreamImpl中了,稍作修訂,即可修正該bug2013-08-08
java求100以內(nèi)的素?cái)?shù)示例分享
素?cái)?shù)是指因數(shù)只有1和本身的數(shù)字,這篇文章主要介紹了java求100以內(nèi)的素?cái)?shù)示例,需要的朋友可以參考下2014-03-03
Java實(shí)現(xiàn)兩人五子棋游戲(二) 畫出棋盤
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)兩人五子棋游戲,畫出五子棋的棋盤,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03

