Java 动态修改注解的属性值

本文介绍了一种在运行环境中动态设置Java注解属性值的方法,通过反射操作修改注解实例的属性,实现Header注解的priority属性根据HeaderGroupConfigure注解的配置动态调整。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以往来看,注解的属性值一般都是“硬编码”。但最近在开发过程中遇到了需要根据运行环境来设置注解属性值的需求。

举个例子:

package com.das.common.util.csv;

import java.lang.annotation.*;

/**
 * @Author liangmy
 * @Date 2018/10/15
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Header {
    String value() default "";
    double priority() default Double.MAX_VALUE;
    String format() default "";
    HeaderGroupConfigure[] groups() default {};
}
package com.das.common.util.csv;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Author liangmy
 * @Date 2019/3/17
 */
@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface HeaderGroupConfigure {
    String headName() default "";
    String groupName();
    double priority() default Double.MAX_VALUE;
    String format() default "";
}

根据HeaderGroupConfigure是否配置priority,修改Header的priority。

 

知识点:

  • 保留策略为 RUNTIME 的注解在运行期是保留的。
  • 出于某些技术原因,Java 虚拟机使用的“真实”注释类的实例是动态代理的实例。
  • Java 注解有一个名为 memberValues 的私有Map,其中存储了属性名称和属性值的k-v对。

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

相关的类:

  • Proxy JDK 动态代理
    可通过其 getInvocationHandler 方法获取注解的代理实例
  • InvocationHandler 调用处理器,每一个被代理的实例都有一个调用处理器
    通过反射获取被代理类的实例的属性值

示例代码:

        // 获取 Header 注解
        Header headerAnnotation = field.getDeclaredAnnotation(Header.class);
        if (null != headerAnnotation) {
            // 获取 Header 中 分组 HeaderGroupConfigure 注解
            HeaderGroupConfigure[] groups = headerAnnotation.groups();
            for (HeaderGroupConfigure group : groups) {
                if (groupNameSet.contains(group.groupName())) {
                    // 计算最终的属性值
                    double groupPriority = Double.MAX_VALUE == group.priority() ? headerAnnotation.priority() : group.priority();
                    // 获取代理处理器
                    InvocationHandler invocationHandler = Proxy.getInvocationHandler(headerAnnotation);
                    // 获取私有 memberValues 属性
                    Field memberValuesField = invocationHandler.getClass().getDeclaredField("memberValues");
                    memberValuesField.setAccessible(true);
                    // 获取实例的属性map
                    Map<String, Object> memberValuesValue = (Map<String, Object>) memberValuesField.get(invocationHandler);
                    // 修改属性值
                    memberValuesValue.put("priority", groupPriority);
                }
            }
        }

略略略

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值