Java中使用注解獲取和改變Bean的指定變量值
Java有時需要通過自定義注解,獲取某Bean的某變量的值,根據(jù)業(yè)務(wù)要求處理數(shù)據(jù),然后再把新值設(shè)置回Bean的同一變量中,下面我們簡要介紹一下,如何實(shí)現(xiàn),
1,自定義注解的定義
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; // 注解的作用范圍,必用, // 如用在類上,方法上,屬性上等,更多參考ElementType枚舉 @Target(ElementType.FIELD) // 注解的生命周期,即注解的保留時間階段,必用, // SOURCE,表示該注解的生命周期只在編譯階段, // CLASS,該注解被保留在class文件上 // RUNTIME,該注解生命周期在運(yùn)行時 @Retention(RetentionPolicy.RUNTIME) // 是一個標(biāo)記注解,沒有定義屬性,作用是為了表示該注解可以被繼承,非必用 // 使用了該元注解的自定義注解,應(yīng)用到某父類上,則該類的子類也默認(rèn)繼承了該注解 // @Inherited // 是一個標(biāo)記注解,里面沒有任何屬性,非必用 // 用 @Documented 注解修飾的注解類會被 JavaDoc 工具提取成文檔 // @Documented // 允許在目標(biāo)對象重復(fù)使用該注解, 指定重復(fù)類,僅參考暫不用,非必用 // @Repeatable(BeanFieldChecks.class) public @interface BeanFieldCheck { /** 校驗(yàn)結(jié)果信息*/ String message()' /** 校驗(yàn)器*/ Class validator(); }
// 僅提供參考,不使用 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface BeanFieldChecks { /** 注解復(fù)數(shù),即同一變量可以多次使用同一注解, 可以不使用,單個注解已可以完成事情 */ BeanFieldCheck[] values(); }
2,注解在Bean中的使用
public class User { @ApiModelProperty(value="主鍵ID") private Long id; // 注解使用 @ApiModelProperty(value="用戶編碼") @JavaField(message="編碼不能為空", validator=UserValidator01.class) private String userCode; // 注解使用 @ApiModelProperty(value="用戶名稱") @JavaField(message="姓名不能含特殊字符和重名", validator=UserValidator02.class) private String userName; @ApiModelProperty(value="年齡") private Interger age; // ...getter/setter省略 }
3,注解的業(yè)務(wù)處理邏輯
根據(jù)注解要求獲取Bean某變量的值,按業(yè)務(wù)要求處理,之后把新值賦給原變量,以UserValidator02.java 為例子:
public class UserValidator02 { // 方法功能:根據(jù)Bean的變量注解,獲取類變量的原值, // 再根據(jù)注解數(shù)據(jù)處理,重新賦給原來的變量 public static <T> T updateModelValue(T bean) { if (null == bean) { return null; } // 獲取目標(biāo)model的java類 Class cls = bean.getClass(); // 獲取類的所有字段變量 Field[] fields = cls.getDeclareFields(); for (Field field : fields) { // 獲取某個類型的注解為: //Annotation an = field.getAnnotation(BeanFieldCheck.class) // 獲取字段的全部注解 Annotation ans = field.getAnnotations(); if (null == ans || ans.length < 1) { continue; } // 遍歷X字段上的所有注解 for (Annotation an : ans) { if (null == an) { continue; } // 對象的變量名, 不做它用,僅顯示用法 String fieldName = field.getName(); // 獲取指定類型注解內(nèi)message的值 String tempVal = ""; if (an instanceof BeanFieldCheck) { // 獲取Bean類變量的該類型注解中message配置項(xiàng)值 BeanFieldCheck anItem = (BeanFieldCheck)an; tempVal = anItem.message(); } try { // 類變量是private私有,需改變?yōu)榭稍L問性 field.setAccessible(true); //獲取類變量的原來值 Object oldVal = field.get(bean); // 這里可根據(jù)自己業(yè)務(wù)要求處理數(shù)據(jù),此處僅簡單暫時 if (null != oldVal) { tempVal = oldVal.toString() + "," + tempVal; } // 將新值賦回類變量的該字段中 field.set(bean, tempVal); // 恢復(fù)變量private特性 field.setAccessible(false); } catch(Exception e) { e.printStackTrace(); } } } //返回修改類變量后的Bean return bean; } // 其它方法省略 }
4,如何觸發(fā)執(zhí)行注解的業(yè)務(wù)邏輯
上面定義了自定義的注解,校驗(yàn)器邏輯,以及注解的使用,但怎么觸發(fā)沒有,
可以通過代碼主動調(diào)用觸發(fā),例如:
User newUser = UserValidator02.updateModelValue(user);
還可以更好一點(diǎn),推薦定義一個AOP切面,讓使用了 BeanFieldCheck 注解的地方在切面中自動觸發(fā)進(jìn)行校驗(yàn)處理,AOP切面不在本中展開,簡要提供如下:
@Component //使該類被springIOC掃描到,交由spring管理 @Aspect //定義為aop切面類 public class UserCheckAspect { // 定義方法作用的目標(biāo)表達(dá)式 @Pointcut(value="@annotation(com.aa.bb.cc.BeanFieldCheck") public void myPointcut01(){} // 根據(jù)需要定義和修改 @Pointcut(value = "execution(* com.aa.bb.cc.BeanFieldCheck..*(..))") public void myPointcut02(){} @Before(value="myPointcut01()") public void beforeExecute(JoinPoint joinPoint){ // 調(diào)用UserValidator02.updateModelValue()處理 //TODO...方法執(zhí)行前的邏輯處理... } @Around(value="myPonitcut01()") public void aroundExecute(ProceedingJoinPoint joinPoint) throws Throwable{ // 調(diào)用UserValidator02.updateModelValue()處理 //TODO...方法執(zhí)行前后的邏輯處理... } @After(value="myPonitcut01()") public void afterExecute(JoinPoint joinPoint) throws Throwable{ // 調(diào)用UserValidator02.updateModelValue()處理 //TODO...方法執(zhí)行后的處理... } }
以上展示了,自定義注解的寫法,應(yīng)用,以及如何通過注解對Java的Bean中某個變量的獲取原值,數(shù)據(jù)處理,賦給原來變量的方法和過程,在實(shí)際使用根據(jù)自己需要相應(yīng)的修改
到此這篇關(guān)于Java中使用注解獲取和改變Bean的指定變量值的文章就介紹到這了,更多相關(guān)Java使用注解獲取改變Bean內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談maven 多環(huán)境打包發(fā)布的兩種方式
這篇文章主要介紹了淺談maven 多環(huán)境打包發(fā)布的兩種方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08java操作mysql實(shí)現(xiàn)增刪改查的方法
這篇文章主要介紹了java操作mysql實(shí)現(xiàn)增刪改查的方法,結(jié)合實(shí)例形式分析了java操作mysql數(shù)據(jù)庫進(jìn)行增刪改查的具體實(shí)現(xiàn)技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-05-05SpringMVC4.3解析器HandlerMethodArgumentResolver接口源碼
這篇文章主要為大家介紹了SpringMVC4.3解析器HandlerMethodArgumentResolver接口源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09java實(shí)現(xiàn)微信企業(yè)付款到個人功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)微信企業(yè)付款到個人功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-09-09Spring Boot通過Redis實(shí)現(xiàn)防止重復(fù)提交
表單提交是一個非常常見的功能,如果不加控制,容易因?yàn)橛脩舻恼`操作或網(wǎng)絡(luò)延遲導(dǎo)致同一請求被發(fā)送多次,本文主要介紹了Spring Boot通過Redis實(shí)現(xiàn)防止重復(fù)提交,具有一定的參考價值,感興趣的可以了解一下2024-06-06Spring/Spring Boot 中優(yōu)雅地做參數(shù)校驗(yàn)拒絕 if/else 參數(shù)校驗(yàn)
這篇文章主要介紹了Spring/Spring Boot 中優(yōu)雅地做參數(shù)校驗(yàn)拒絕 if/else 參數(shù)校驗(yàn),本文使用最新的 Spring Boot 版本 2.4.5,通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-04-04Spring實(shí)現(xiàn)在非controller中獲取request對象
這篇文章主要介紹了Spring實(shí)現(xiàn)在非controller中獲取request對象方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08spring mvc+localResizeIMG實(shí)現(xiàn)HTML5端圖片壓縮上傳
這篇文章主要為大家詳細(xì)介紹了使用spring mvc+localResizeIMG實(shí)現(xiàn)HTML5端圖片壓縮上傳,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04