Java中使用注解獲取和改變Bean的指定變量值
Java有時需要通過自定義注解,獲取某Bean的某變量的值,根據(jù)業(yè)務(wù)要求處理數(shù)據(jù),然后再把新值設(shè)置回Bean的同一變量中,下面我們簡要介紹一下,如何實現(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,該注解生命周期在運行時
@Retention(RetentionPolicy.RUNTIME)
// 是一個標(biāo)記注解,沒有定義屬性,作用是為了表示該注解可以被繼承,非必用
// 使用了該元注解的自定義注解,應(yīng)用到某父類上,則該類的子類也默認繼承了該注解
// @Inherited
// 是一個標(biāo)記注解,里面沒有任何屬性,非必用
// 用 @Documented 注解修飾的注解類會被 JavaDoc 工具提取成文檔
// @Documented
// 允許在目標(biāo)對象重復(fù)使用該注解, 指定重復(fù)類,僅參考暫不用,非必用
// @Repeatable(BeanFieldChecks.class)
public @interface BeanFieldCheck {
/** 校驗結(jié)果信息*/
String message()'
/** 校驗器*/
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配置項值
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ù)邏輯
上面定義了自定義的注解,校驗器邏輯,以及注解的使用,但怎么觸發(fā)沒有,
可以通過代碼主動調(diào)用觸發(fā),例如:
User newUser = UserValidator02.updateModelValue(user);
還可以更好一點,推薦定義一個AOP切面,讓使用了 BeanFieldCheck 注解的地方在切面中自動觸發(fā)進行校驗處理,AOP切面不在本中展開,簡要提供如下:
@Component //使該類被springIOC掃描到,交由spring管理
@Aspect //定義為aop切面類
public class UserCheckAspect {
// 定義方法作用的目標(biāo)表達式
@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ù)處理,賦給原來變量的方法和過程,在實際使用根據(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-08
SpringMVC4.3解析器HandlerMethodArgumentResolver接口源碼
這篇文章主要為大家介紹了SpringMVC4.3解析器HandlerMethodArgumentResolver接口源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09
Spring Boot通過Redis實現(xiàn)防止重復(fù)提交
表單提交是一個非常常見的功能,如果不加控制,容易因為用戶的誤操作或網(wǎng)絡(luò)延遲導(dǎo)致同一請求被發(fā)送多次,本文主要介紹了Spring Boot通過Redis實現(xiàn)防止重復(fù)提交,具有一定的參考價值,感興趣的可以了解一下2024-06-06
Spring/Spring Boot 中優(yōu)雅地做參數(shù)校驗拒絕 if/else 參數(shù)校驗
這篇文章主要介紹了Spring/Spring Boot 中優(yōu)雅地做參數(shù)校驗拒絕 if/else 參數(shù)校驗,本文使用最新的 Spring Boot 版本 2.4.5,通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2021-04-04
Spring實現(xiàn)在非controller中獲取request對象
這篇文章主要介紹了Spring實現(xiàn)在非controller中獲取request對象方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
spring mvc+localResizeIMG實現(xiàn)HTML5端圖片壓縮上傳
這篇文章主要為大家詳細介紹了使用spring mvc+localResizeIMG實現(xiàn)HTML5端圖片壓縮上傳,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04

