java注解之運(yùn)行時(shí)修改字段的注解值操作
今天遇到需求:導(dǎo)入Excel時(shí)候列頭會發(fā)生變化,客戶是大爺要求你改代碼,
導(dǎo)入Excel是用easypoi做的,識別表頭是用注解@Excel(name = "xxx")通過這個(gè)name來匹配
那你表頭要動,我這個(gè)注解是硬編碼
所以就有動態(tài)設(shè)置這個(gè)表頭
public class JavaVo{
@Excel(name = "xxx")
private String userName;
//省略getset方法
}
ExcelImportUtil.importExcel(file.getInputStream(), configClass(JavaVo.class), params);
代碼如下
private Class configClass(Class c , String val) {
Field[] fields = c.getDeclaredFields();
try {
for(int i = 0;i < fields.length;i++){
Field f = fields[i];
Excel excelAn = f.getAnnotation(Excel.class);//Excel是注解類型
if(excelAn == null){
continue;
}
InvocationHandler h = Proxy.getInvocationHandler(excelAn);
Field hField = h.getClass().getDeclaredField("memberValues");
// 因?yàn)檫@個(gè)字段事 private final 修飾,所以要打開權(quán)限
hField.setAccessible(true);
// 獲取 memberValues
Map memberValues = (Map) hField.get(h);
// 修改 value 屬性值 這里修改的是@Excel(name = "姓名")
//name是key
memberValues.put("name", val);
}
} catch (Exception e) {
e.printStackTrace();
}
return c;
}
補(bǔ)充知識:java動態(tài)修改 注解的值,控制對象轉(zhuǎn)化為json字符串的字段是否序列化
定義一個(gè)對象使用@JSONField控制該對象屬性是否需要序列化
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
@Data
public class A {
@JSONField(serialize = false)
private String extendParams;
@JSONField(serialize = true)
private String sad;
}
編寫工具類
import com.alibaba.fastjson.annotation.JSONField;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Map;
import lombok.val;
/**
* 動態(tài)操作注解屬性
* @since 2020年8月13日20:49:26
*/
public class AnnotationUtils<T> {
/**
* 查看注解屬性
* @param t
* @param name
* @return
* @throws NoSuchFieldException
*/
public Object getJSONFieldProp(T t, String name) throws NoSuchFieldException {
Field field = t.getClass().getDeclaredField(name);
JSONField annotation = field.getAnnotation(JSONField.class);
val serialize = annotation.serialize();
return serialize;
}
/**
* 修改注解屬性
* @param t
* @param value
* @return
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
public Object setJSONFieldProp(T t,String name, Object value) throws NoSuchFieldException, IllegalAccessException {
Field field = t.getClass().getDeclaredField(name);
JSONField annotation = field.getAnnotation(JSONField.class);
InvocationHandler invocationHandler = Proxy.getInvocationHandler(annotation);
Field memberValues = invocationHandler.getClass().getDeclaredField("memberValues");
memberValues.setAccessible(true);
Map map = (Map) memberValues.get(invocationHandler);
map.put("serialize",value);
val serialize = annotation.serialize();
return serialize;
}
}
測試
import com.alibaba.fastjson.JSON;
public class TT {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
AnnotationUtils<A> aAnnotationUtils = new AnnotationUtils<>();
A a = new A();
a.setExtendParams("exex");
a.setSad("sadsad");
Object extendParams = aAnnotationUtils.getJSONFieldProp(a, "extendParams");//查詢注解的值
System.out.println(extendParams.toString());
// System.out.println(JSON.toJSONString(a));
Object extendParams1 = aAnnotationUtils.setJSONFieldProp(a, "extendParams", true);//修改注解的值
System.out.println(extendParams1.toString());
System.out.println(JSON.toJSONString(a));
}
}
去掉main里面的注解看看效果,這個(gè)好像是發(fā)生了jvm優(yōu)化導(dǎo)致的問題。。。
注釋第一個(gè)print 打印結(jié)果如下:
false
true
{"extendParams":"exex","sad":"sadsad"}
不注釋第一個(gè)print 打印結(jié)果如下:
false
{"sad":"sadsad"}
true
{"sad":"sadsad"}
接下來我們在做一個(gè)測試
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
List<A> aList = new ArrayList<>();
for(int i=0; i<10; i++){
AnnotationUtils<A> aAnnotationUtils = new AnnotationUtils<>();
A a = new A();
a.setExtendParams("exex");
a.setSad("sadsad");
if(i%2 == 0) {
aAnnotationUtils.setJSONFieldProp(a, "extendParams", true);//修改注解的值
}
aList.add(a);
}
System.out.println(JSON.toJSONString(aList));
}
打印結(jié)果
[{"extendParams":"exex","sad":"sadsad"},{"extendParams":"exex","sad":"sadsad"},{"extendParams":"exex","sad":"sadsad"},{"extendParams":"exex","sad":"sadsad"},{"extendParams":"exex","sad":"sadsad"},{"extendParams":"exex","sad":"sadsad"},{"extendParams":"exex","sad":"sadsad"},{"extendParams":"exex","sad":"sadsad"},{"extendParams":"exex","sad":"sadsad"},{"extendParams":"exex","sad":"sadsad"}]
我本想用修改注解的方式來修改某個(gè)字段的序列化與不序列化,但是我發(fā)現(xiàn)注解是在class層面的并不是在對象層面。所以我的設(shè)想失敗了。。
以上這篇java注解之運(yùn)行時(shí)修改字段的注解值操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- java注解結(jié)合aspectj AOP進(jìn)行日志打印的操作
- 如何動態(tài)修改JavaBean中注解的參數(shù)值
- java使用@Scheduled注解執(zhí)行定時(shí)任務(wù)
- Java中l(wèi)ombok的@Builder注解的解析與簡單使用詳解
- java 注解默認(rèn)值操作
- 解決IDEA導(dǎo)入javaWeb項(xiàng)目注解爆紅的問題
- javax.validation自定義日期范圍校驗(yàn)注解操作
- 談?wù)凧ava中自定義注解及使用場景
- Java如何使用JSR303校驗(yàn)數(shù)據(jù)與自定義校驗(yàn)注解
- java SpringBoot自定義注解,及自定義解析器實(shí)現(xiàn)對象自動注入操作
- Java 注解學(xué)習(xí)筆記
相關(guān)文章
SpringCloud feign服務(wù)熔斷下的異常處理操作
這篇文章主要介紹了SpringCloud feign服務(wù)熔斷下的異常處理操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
spring?kafka?@KafkaListener詳解與使用過程
這篇文章主要介紹了spring-kafka?@KafkaListener詳解與使用,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02
Java Builder模式實(shí)現(xiàn)原理及優(yōu)缺點(diǎn)解析
這篇文章主要介紹了Java Builder模式實(shí)現(xiàn)原理及優(yōu)缺點(diǎn)解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
用SpringBoot Admin監(jiān)控SpringBoot程序
這篇文章主要介紹了用SpringBoot Admin監(jiān)控SpringBoot程序,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下2020-10-10
springsecurity第三方授權(quán)認(rèn)證的項(xiàng)目實(shí)踐
Spring security 是一個(gè)強(qiáng)大的和高度可定制的身份驗(yàn)證和訪問控制框架,本文主要介紹了springsecurity第三方授權(quán)認(rèn)證的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣可以了解一下2023-08-08
Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(59)
下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你2021-08-08
springboot 在ftl頁面上使用shiro標(biāo)簽的實(shí)例代碼
這篇文章主要介紹了springboot 在ftl頁面上使用shiro標(biāo)簽的實(shí)例代碼,通過文字說明結(jié)合實(shí)例的形式給大家介紹的非常詳細(xì),需要的朋友參考下吧2018-05-05
Java高性能實(shí)體類轉(zhuǎn)換工具M(jìn)apStruct的使用教程詳解
MapStruct 是一個(gè)代碼生成器,它基于約定優(yōu)于配置的方法,極大地簡化了 Java bean 類型之間的映射實(shí)現(xiàn),本文主要介紹了MapStruct的具體使用以及如何進(jìn)行實(shí)體類轉(zhuǎn)換,感興趣的可以了解下2024-03-03

