精华内容
下载资源
问答
  • java 动态修改方法上的注解值

    万次阅读 热门讨论 2018-04-15 22:35:18
    上篇博客提起,动态修改类上注解的值。有博友问题如果修改方法注解值,其实二者是相通的。 代码如下: import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import j...

    https://blog.csdn.net/jiangzeyin_/article/details/78421178

    上篇博客提起,动态修改类上注解的值。有博友问题如果修改方法上注解值,其实二者是相通的。

    代码如下:

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * Created by jiangzeyin on 2018/4/15.
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface testA {
        String value();
    }
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.util.Map;
    
    /**
     * Created by jiangzeyin on 2018/4/15.
     */
    public class test {
    
        @testA("a")
        public static void main(String[] args) throws Exception {
            Method method = test.class.getMethod("main", String[].class);
            testA testA = method.getAnnotation(testA.class);
            if (testA == null)
                throw new RuntimeException("please add testA");
            InvocationHandler invocationHandler = Proxy.getInvocationHandler(testA);
            Field value = invocationHandler.getClass().getDeclaredField("memberValues");
            value.setAccessible(true);
            Map<String, Object> memberValues = (Map<String, Object>) value.get(invocationHandler);
            String val = (String) memberValues.get("value");
            System.out.println("改变前:" + val);
            val = "b";
            memberValues.put("value", val);
            System.out.println("改变后:" + testA.value());
    
        }
    }
    

    运行结果:
    这里写图片描述

    展开全文
  • 动态修改注解值

    千次阅读 2019-10-20 22:44:41
    公司使用的配置中心是自研发的,暂不支持配置中心注解(如:@DynamicPropertyInject(name = "${application.effective.exchanges}"))的采用properties文件来动态配置。这使得在同套代码的不同应用场景下,表明同...

    背景

    平时开发业务时,由于特殊需要,使得一份代码需要部署到4个应用服务中为不同对象进行服务。公司使用的配置中心是自研发的,暂不支持配置中心注解(如:@DynamicPropertyInject(name = "${application.effective.exchanges}"))的值采用properties文件来动态配置。这使得在同套代码的不同应用场景下,表明同个含义的注入就需要声明多次,且有且仅只有一个声明对于当前应用是有效的。从简洁的角度来说不适合。

    示例注解:

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD}
    public @interface DynamicPropertyInject {
        String name() default '';
    }
    

    不能依据properties注入的代码情形:

    public class DynamicConfiguration {
        @DynamicPropertyInject(name = "application1.effective.name")
        private String application1ExchangeName;
    
        @DynamicPropertyInject(name = "application2.effective.name")
        private String application2ExchageName;
    
        @DynamicPropertyInject(name = "application3.effective.name")
        private String application3ExchangeName;
    }
    

    其实在每个应用中,仅只有application1ExchangeNameapplication2ExchangeNameapplication3ExchangeName其中之一有效。

    能依据properties注入的代码情形:

    public class DynamicConfiguration {
        @DynamicPropertyInject(name = "${application.effective.name}")
        private String applicationExchangeName;
    }
    

    解决:

    针对如上所述的场景,其实要解决的是来获取applicationExchangeName的时候,需要根据当前的应用名称来取其对应的值。很自然的,第一反应是通过反射来获取注解属性的值并修改之。

    在这里提供下思路:

    1. DynamicConfiguration的类定义切面;
    2. 程序执行到注解DynamicPropertyInject时,判断是否需要去修改值。是则修改,否则跳过。
    public class DynamicConfigValueAspect {
    
        public static final String CHARACTER_DOLLAR = "$";
        public static final String CHARACTER_NUMBERSIGN = "#";
        
        @Autowired
        private ApplicationProperties applicationProperties;
    
        @Around("this(package of DynamicConfiguration)")
        public Object around(ProceedingJoinPoint pjp) throws Throwable {
            String methodName = pjp.getSignature().getName();
            if (methodName.startsWith("get") && methodName.length() >= 4) {
                //提取属性名
                String fieldName = methodName.substring(3, 4).toLowerCase() + methodName.substring(4);
                Field field = pjp.getTarget().getClass().getDeclaredField(fieldName);
                DynamicPropertyInject configuration = field.getAnnotation(DynamicPropertyInject.class);
    
                String configName = configuration.name();
                //属性的DynamicPropertyInject注解值是否需要修改
                if (StringUtils.isNotBlank(configName) && StringUtils.startsWith(configName, CHARACTER_DOLLAR) || StringUtils.startsWith(configName, CHARACTER_NUMBERSIGN)) {
                    InvocationHandler invocationHandler = Proxy.getInvocationHandler(configuration);
                    Field declaredField = invocationHandler.getClass().getDeclaredField("memberValues");
                    declaredField.setAccessible(true);
                    Map memberValues = (Map) declaredField.get(invocationHandler);
                    //获取修改的值并修改
                    memberValues.put("name", getApplicationPropertiesByConfigElement(configName));
                }
            }
    
            return pjp.proceed();
        }
        
        //获取修改的值
        private String getApplicationPropertiesByConfigElement(String configName) throws IllegalAccessException {
            Field[] fields = ApplicationProperties.class.getDeclaredFields();
            if (ArrayUtils.isEmpty(fields)) {
                return null;
            }
    
            for (Field field : fields) {
                Value annotation = field.getAnnotation(Value.class);
                if (Objects.nonNull(annotation) && StringUtils.equals(configName, annotation.value())) {
                    field.setAccessible(true);
                    return String.valueOf(field.get(applicationProperties));
                }
            }
    
            return null;
        }
    
    }
    
    
    //application property
    @Configuration
    public class ApplicationProperties {
        @Value("${application.effective.name}")
        private String applicationEffectiveName;
    }
    
    展开全文
  • Java 反射动态获取和修改注解值Java 反射动态获取和修改注解值创建自定义注解:`TargetAnnotation.java`创建自定义注解:`Property.java`创建测试Bean:`Bean.java`测试测试结果 Java 反射动态获取和修改注解值 ...

    Java 反射动态获取和修改注解值

    目的:通过注解 TargetAnnotation 的配置,动态获取和修改注解 Property

    创建自定义注解:TargetAnnotation.java

    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Documented
    @Target(ElementType.FIELD)
    @Retention(value = RetentionPolicy.RUNTIME)
    public @interface TargetAnnotation {
        /**
         * 目标注解类
         */
        Class<?> targetAnnotationClass() default Void.class;
    
        /**
         * 目标注解属性
         */
        String targetAnnotationClassField() default "";
    }
    

    创建自定义注解:Property.java

    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Documented
    @Target(ElementType.FIELD)
    @Retention(value = RetentionPolicy.RUNTIME)
    public @interface Property {
    
        String name() default "";
    }
    

    创建测试Bean:Bean.java

    public class Bean {
        
        @Property(name = "名称")
        @TargetAnnotation(targetAnnotationClass = Property.class , targetAnnotationClassField = "name")
        private String name;
    }
    

    测试

    import java.lang.annotation.Annotation;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;
    import java.util.Map;
    
    public class Test {
    
        public static void main(String[] args) throws Exception {
            Field nameField = Bean.class.getDeclaredField("name");
    
            TargetAnnotation targetAnnotation = nameField.getAnnotation(TargetAnnotation.class);
    
            // 获取标注的目标注解类
            Class<? extends Annotation> targetAnnotationClass = (Class<? extends Annotation>) targetAnnotation.targetAnnotationClass();
    
            // 获取 TargetAnnotation.targetAnnotationClass 标注的注解代理实例
            Annotation annotation = nameField.getAnnotation(targetAnnotationClass);
    
            // 获取代理实例所持有的 InvocationHandler
            InvocationHandler invocationHandler = Proxy.getInvocationHandler(annotation);
    
            // 获取 AnnotationInvocationHandler 的 memberValues 字段
            Field memberValuesField = invocationHandler.getClass().getDeclaredField("memberValues");
    
            // 打开访问权限
            memberValuesField.setAccessible(true);
    
            // 获取 memberValues (目标注解的信息都在 memberValues 中)
            Map memberValues = (Map) memberValuesField.get(invocationHandler);
    
            // 1)、动态获取 TargetAnnotation.targetAnnotationClassField 标注的注解属性值
            Object targetAnnotationClassField = memberValues.get(targetAnnotation.targetAnnotationClassField());
            System.out.println("修改前:" + targetAnnotationClassField);
    
            // 2)、动态修改 TargetAnnotation.targetAnnotationClassField 标注的注解属性值
            memberValues.put(targetAnnotation.targetAnnotationClassField(), "用户名");
    
            // 3)、再次获取修改后的 TargetAnnotation.targetAnnotationClassField 标注的注解属性值
            targetAnnotationClassField = memberValues.get(targetAnnotation.targetAnnotationClassField());
            System.out.println("修改后:" + targetAnnotationClassField);
        }
    }
    

    测试结果

    修改前:名称
    修改后:用户名
    
    展开全文
  • Java运行时反射修改注解值

    千次阅读 2018-11-12 16:11:30
    Java实现运行时修改注解值 由于java的注解不能传参,而项目中经常需要将运行中动态值传到注解中,因为需要在运行中修改注解的值,达到我们想要的目的。再次记录我项目中实现java通过反射实现运行时修改注解值。 ...

    Java实现运行时修改注解值

    由于java的注解不能传参,而项目中经常需要将运行中动态值传到注解中,因为需要在运行中修改注解的值,达到我们想要的目的。再次记录我项目中实现java通过反射实现运行时修改注解值。

    实践

        private void changeTimerConfig() {
            try {
                Method doJob = SynTaskTimer.class.getMethod("doJob");
                Scheduled annotation = doJob.getAnnotation(Scheduled.class);
                if (annotation != null){
                    InvocationHandler invocationHandler = Proxy.getInvocationHandler(annotation);
                    Field values = invocationHandler.getClass().getDeclaredField("memberValues");
                    values.setAccessible(true);
                    Map<String, Object> memberValues =(Map<String, Object>) values.get(invocationHandler);
                    long val = (long) memberValues.get("fixedRate");
                    System.out.println("改变前:"  + val);
                    memberValues.put("fixedRate", SysConfig.schedulerRate);
                    System.out.println("改变后:"  + annotation.fixedRate());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }*
    

    membervalues 为JDK中存储所有成员变量值的Map

    展开全文
  • 反射做不到.Thread里只提供方法名,不过既然有方法名,是不是里面得到过Method对象? 咱也能问,方法内部能不能获取当前方法对象?求哪位解答
  • Java 使用动态代理来动态修改注解值

    万次阅读 2017-11-02 09:32:17
    java 中定义注解都是在编写代码时,如果我们想在运行中根据某个条件来修改注解。是无法注解操作的,但是通过动态代理是可以实现的。这里需要用到的是Proxy 动态代理第一步得到代理实例:InvocationHandler ...
  • 采用spring的AOP切面思想,对需要监控记录的方法动作设置切点(自定义注解的方式),同时利用java的反射原理实现动态修改方法上的注解值&amp;amp;amp;amp;amp;gt; 一 AOP的基本概念 (1)Aspect(切面):通常是一...
  • 本文讨论如何在运行时修改注解值,我们示例使用类级别注解。 1. 注解 Java允许使用现有注解创建新的注解。最简单的注释形式是@符号后接注释名: @Override 下面创建自定义注解Greeter: @Retention(RetentionPolicy....
  • java中元注解有四个: @Retention @Target @Document @Inherited; @Retention:注解的保留位置  @Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含 @Retention...
  • Java反射动态修改注解

    千次阅读 2018-03-11 14:48:47
    先来看看通常情况下,我们通过反射获取注解的场景:那么现在我们定义一个 @Foo 注解,它有一个类型为 String 的 value 属性,该注解应用再Field上:/** * @Author 落叶飞翔的蜗牛 * @Date 2018/3/11 * @...
  • Java中修改注解属性

    千次阅读 2018-04-20 09:12:48
    RibbonClient client = ConsumerApplication.class.getAnnotation(RibbonClient.class); Class[] configuration = client.configuration();...该处是修改类上的注解,至于修改方法,属性上的注解同理;
  • JAVA使用变量动态修改注解属性

    千次阅读 2020-07-17 14:51:14
    JAVA使用变量动态修改注解属性问题场景反射基础动态修改注解属性的实现问题场景的修复 问题场景 在使用easyexcel做数据导出时,用到了注解@ExcelProperty标记表头,代码如下: import ...
  •  首先有块业务,需要添加埋点内容,但是此处埋点在入参中有一个字段,这个字段的不同,会发送不同的打点信息(这个是在接口返回正确的情况下调用的),奔着解耦原业务和埋点的出发点,于是选择利用注解和...
  • Java动态修改注解的属性

    千次阅读 2019-06-13 19:10:01
    以往来看,注解的属性一般都是“硬编码”。但最近在开发过程中遇到了需要根据运行环境来设置Retention 为 RUNTIME (运行期保留)的注解属性的需求。举个例子: @Table(name="t1") public class Test { private...
  • 这个题目我并不是很熟悉,不过根据题目描述和查阅相关Spring 创建定时任务的资料,发现这也许涉及到通过Java代码动态修改注解的属性。 今天对此尝试了一番,发现通过反射来动态修改注解的属性是可以做到的: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 150,344
精华内容 60,137
关键字:

方法内修改注解的值