java中注解动态传参_Java 动态修改注解的属性值

本文介绍了如何在运行时根据环境动态修改Java注解的属性值,例如@Table注解的name属性。通过反射访问注解的InvocationHandler,利用Java动态代理机制,可以修改私有的memberValues属性,实现测试环境与生产环境的配置差异化。
摘要由CSDN通过智能技术生成

前言

以往来看,注解的属性值一般都是“硬编码”。但最近在开发过程中遇到了需要根据运行环境来设置 Retention 为 RUNTIME (运行期保留) 的注解属性值的需求。举个例子:

@Table(name="t1")

public class Test {

private String id;

...

}

对于上述类 Test,其上有一个注解 @Table,需求是这样的: 在测试环境 name 值为"t1",在其他环境 name 值为"t2"。

实现方法

知识点:

保留策略为 RUNTIME 的注解在运行期是保留的。

出于某些技术原因,Java 虚拟机使用的“真实”注释类的实例是动态代理的实例。

Java 注解有一个名为 memberValues 的私有Map,其中存储了属性名称和属性值的k-v对。

基于上述知识点,可以通过反射来访问实例,然后用给定的新值替换现有值。

相关的类:

Proxy JDK 动态代理大佬

可通过其 getInvocationHandler 方法获取注解的代理实例

InvocationHandler 调用处理器,每一个被代理的实例都有一个调用处理器

通过反射获取被代理类的实例的属性值

示例代码:

// 根据运行环境获取表名

String tableName = getTable();

// 获取 Test 上的注解

Table annoTable = Test.class.getAnnotation(Table.class);

if (annoTable == null) {

throw new RuntimeException("please add @Table for Test");

}

// 获取代理处理器

InvocationHandler invocationHandler = Proxy.getInvocationHandler(annoTable);

// 过去私有 memberValues 属性

Field f = invocationHandler.getClass().getDeclaredField("memberValues");

f.setAccessible(true);

// 获取实例的属性map

Map memberValues = (Map) f.get(invocationHandler);

// 修改属性值

memberValues.put("name", tableName);

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值