Java中使用注解獲取和改變Bean的指定變量值
Java有時(shí)需要通過自定義注解,獲取某Bean的某變量的值,根據(jù)業(yè)務(wù)要求處理數(shù)據(jù),然后再把新值設(shè)置回Bean的同一變量中,下面我們簡(jiǎn)要介紹一下,如何實(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)
// 注解的生命周期,即注解的保留時(shí)間階段,必用,
// SOURCE,表示該注解的生命周期只在編譯階段,
// CLASS,該注解被保留在class文件上
// RUNTIME,該注解生命周期在運(yùn)行時(shí)
@Retention(RetentionPolicy.RUNTIME)
// 是一個(gè)標(biāo)記注解,沒有定義屬性,作用是為了表示該注解可以被繼承,非必用
// 使用了該元注解的自定義注解,應(yīng)用到某父類上,則該類的子類也默認(rèn)繼承了該注解
// @Inherited
// 是一個(gè)標(biāo)記注解,里面沒有任何屬性,非必用
// 用 @Documented 注解修飾的注解類會(huì)被 JavaDoc 工具提取成文檔
// @Documented
// 允許在目標(biāo)對(duì)象重復(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ù),即同一變量可以多次使用同一注解,
可以不使用,單個(gè)注解已可以完成事情 */
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) {
// 獲取某個(gè)類型的注解為:
//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;
}
// 對(duì)象的變量名, 不做它用,僅顯示用法
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ù),此處僅簡(jiǎn)單暫時(shí)
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ā)沒有,
可以通過代碼主動(dòng)調(diào)用觸發(fā),例如:
User newUser = UserValidator02.updateModelValue(user);
還可以更好一點(diǎn),推薦定義一個(gè)AOP切面,讓使用了 BeanFieldCheck 注解的地方在切面中自動(dòng)觸發(fā)進(jìn)行校驗(yàn)處理,AOP切面不在本中展開,簡(jiǎn)要提供如下:
@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)用,以及如何通過注解對(duì)Java的Bean中某個(gè)變量的獲取原值,數(shù)據(jù)處理,賦給原來變量的方法和過程,在實(shí)際使用根據(jù)自己需要相應(yīng)的修改
到此這篇關(guān)于Java中使用注解獲取和改變Bean的指定變量值的文章就介紹到這了,更多相關(guān)Java使用注解獲取改變Bean內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot+vue實(shí)現(xiàn)登錄圖片驗(yàn)證碼功能
這篇文章主要給大家介紹一下如何SpringBoot+vue實(shí)現(xiàn)登錄圖片驗(yàn)證碼功能,文中有詳細(xì)的代碼示例,具有一定的參考價(jià)值,需要的朋友可以參考下2023-07-07
springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服務(wù)的坑
這篇文章主要介紹了springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服務(wù)的坑,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-06-06
Java 日期格式加上指定月數(shù)(一個(gè)期限)得到一個(gè)新日期的實(shí)現(xiàn)代碼
這篇文章主要介紹了Java 日期格式加上指定月數(shù)(一個(gè)期限)得到一個(gè)新日期的實(shí)現(xiàn)代碼,需要的朋友可以參考下2018-05-05
JavaEE通過response實(shí)現(xiàn)請(qǐng)求重定向
這篇文章主要介紹了JavaEE通過response實(shí)現(xiàn)請(qǐng)求重定向的方法,非常的簡(jiǎn)單實(shí)用,有需要的朋友可以參考下2014-10-10
SpringBoot3.x版本與Mybatis-Plus不兼容問題
當(dāng)使用3.x版本的SpringBoot結(jié)合Mybatis-Plus時(shí)版本不兼容就會(huì)報(bào)錯(cuò),本文就來介紹一下這個(gè)問題的解決方法,感興趣的可以了解一下2024-03-03

