这是最近朋友的一个需求,正好闲来无聊有些时间,跟着研究一下,如有不正确的地方,欢迎大家指正~

一、准备自定义注解

  注:如何实现自定义注解,请移步百度。

二、实现

1、实现方式1:通过反射+动态代理动态修改自定义注解的属性

public class ModifyAnnotaionFactory {
private static ModifyAnnotaionFactory instance = null;
public static ModifyAnnotaionFactory newInstance()
{ if (instance == null)
{
synchronized (ModifyAnnotaionFactory.class)
{
if (instance == null)
{
instance = new ModifyAnnotaionFactory();
}
}
} return instance;
}
private ModifyAnnotaionFactory(){} /**
*
* @param className 当前类名.class
* @param annotationName 需要修改的注解class
* @param methodName 需要修改的方法名
* @param modifyField 注解中需要修改的属性名
* @param paramName 注解中修改的属性值
* @param paramTypes 不定参数----语法糖
*/
public Annotation ModifyAnnotation(Class className,Class annotationName,
String methodName,String modifyField,String paramName,Class<?>... paramTypes)
{
try
{
//反射获取Method:methodName方法、paramTypes不定参数(“语法糖”)-----method
Method method = className.getDeclaredMethod(methodName,paramTypes);
//反射当前方法的注解---annotation
Annotation annotation = method.getAnnotation(annotationName);
//获取该注解的调用处理器---invocationHandler
InvocationHandler invocationHandler = Proxy.getInvocationHandler(annotation);
//反射获取注解的属性
Field memberValues = invocationHandler.getClass().getDeclaredField("memberValues");
//暴力破解
memberValues.setAccessible(true);
//获取所有的注解属性--map集合
Map<String, Object> values = (Map<String, Object>) memberValues.get(invocationHandler);
//覆盖原有属性值
values.put(modifyField, paramName);
return annotation;
} catch (Exception e) {
e.printStackTrace();
return null;
}
} /**
*
* @param classAllPath 当前类的全路径名
* @param annotationName 需要修改的注解class
* @param methodName 需要修改的方法名
* @param modifyField 注解中需要修改的属性名
* @param paramName 注解中修改的属性值
* @return
*/
public boolean ModifyAnnotation(String classAllPath,Class annotationName,String methodName,String modifyField,String paramName)
{
try
{
Class<?> aClass = Class.forName(classAllPath);
Method method = aClass.getDeclaredMethod(methodName);
Annotation annotation = method.getAnnotation(annotationName);
InvocationHandler invocationHandler = Proxy.getInvocationHandler(annotation);
Field memberValues = invocationHandler.getClass().getDeclaredField("memberValues");
memberValues.setAccessible(true);
Map<String, Object> values = (Map<String, Object>) memberValues.get(invocationHandler); Object o1 = values.get(modifyField);
values.put(modifyField, paramName);
Object o2 = values.get(modifyField);
System.out.println();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 获取当前注解
* @param className 当前类名
* @param annotationName 注解名
* @param name 方法名、类名、属性名之一
* @param type 注解类型
* @return
* @throws Exception
*/
public Annotation getAnnotation(Class className,Class annotationName,String name,Integer type) throws Exception {
switch (type){
case 1:
Method method = className.getDeclaredMethod(name);
return method.getAnnotation(annotationName);
case 2:
System.out.println("2");
return null;
case 3:
System.out.println("3");
return null;
}
return null;
}

工具类

测试结果如下:

2、实现方式2:

JDK动态代理+反射实现动态修改注解属性值的更多相关文章

  1. Java反射之Bean修改更新属性值等工具类

    package com.bocean.util; import java.lang.annotation.Annotation; import java.lang.reflect.Field; imp ...

  2. 杨晓峰-Java核心技术-6 动态代理 反射 MD

    目录 第6讲 | 动态代理是基于什么原理? 典型回答 考点分析 知识扩展 反射机制及其演进 动态代理 精选留言 Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAnd ...

  3. 从静态代理,jdk动态代理到cglib动态代理-一文搞懂代理模式

    从代理模式到动态代理 代理模式是一种理论上非常简单,但是各种地方的实现往往却非常复杂.本文将从代理模式的基本概念出发,探讨代理模式在java领域的应用与实现.读完本文你将get到以下几点: 为什么需要 ...

  4. 浅谈Spring中JDK动态代理与CGLIB动态代理

    前言Spring是Java程序员基本不可能绕开的一个框架,它的核心思想是IOC(控制反转)和AOP(面向切面编程).在Spring中这两个核心思想都是基于设计模式实现的,IOC思想的实现基于工厂模式, ...

  5. 代理模式详解:静态代理、JDK动态代理与Cglib动态代理

    代理模式简介分类 概念 ​ 代理,是为了在不修改目标对象的基础上,增强目标方法的业务逻辑. ​ 客户类需要执行的是目标对象的目标方法,但是真正执行的是代理对象的代理方法,客户类对目标对象的访问是通过代 ...

  6. JDK 动态代理与 CGLIB 动态代理,它俩真的不一样

    摘要:一文带你搞懂JDK 动态代理与 CGLIB 动态代理 本文分享自华为云社区<一文带你搞懂JDK 动态代理与 CGLIB 动态代理>,作者: Code皮皮虾 . 两者有何区别 1.Jd ...

  7. 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理

    Spring AOP详解 . JDK动态代理.CGLib动态代理  原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...

  8. jdk动态代理与cglib动态代理例子

    1.JAVA的动态代理特征:特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象 ...

  9. Java代理(静态代理、JDK动态代理、CGLIB动态代理)

    Java中代理有静态代理和动态代理.静态代理的代理关系在编译时就确定了,而动态代理的代理关系是在运行期确定的.静态代理实现简单,适合于代理类较少且确定的情况,而动态代理则给我们提供了更大的灵活性. J ...

随机推荐

  1. Appium+Python移动端(Android)自动化测试环境搭建

    一.安装JDK 下载好jdk安装包后直接下一步直至安装完成即可,安装完JDK后配置环境变量 :计算机→属性→高级系统设置→高级→环境变量: 系统变量→新建 JAVA_HOME 变量 变量值填写jdk的 ...

  2. Docker最全教程——从理论到实战(十)

    终于按时完成第二篇.本来准备着手讲一些实践,但是数据库部分没有讲到,部分实践会存在一些问题,于是就有了此篇以及后续——数据库容器化.本篇将从SQL Server容器化实践开始,并逐步讲解其他数据库的容 ...

  3. 浅谈C#委托的用法-delegate

    2018年11月7日     小雨 一.委托的概念 委托和类一样是一种用户自定义类型,它存储的就是一系列具有相同签名和返回类型的方法的地址,调用委托的时候,它所包含的所有方法都会被执行. 借用百度上的 ...

  4. JS高级---案例:验证用户输入的是不是邮箱

    案例:验证用户输入的是不是邮箱 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...

  5. Tomcatd断点调试Debug

    ideaDebug设置

  6. 04 部署uwsgi web服务器

    1 建立uwsgi软链接 进入虚拟环境,并在虚拟环境中安装uwsgi,建立软链接. $ cd /venv/thvenv/bin $ activate $ pip install uwsgi 2 创建u ...

  7. Mapper-元素和属性

    Mapper.xml文件内部的元素和属性     parameterType(输入类型) §  传递简单类型 §  使用#{}占位符,或者${}进行sql拼接, #{}括号中的值可以任意, ${}括号 ...

  8. django 完成登录功能

    啃了几天文档,感觉能理解了这个框架,但是真的下手的时候真的不知道从何开始. orm即Object-Relationl Mapping,看这名字就是操作数据库的,用过ssm,不过django操作数据库是 ...

  9. springboot中集成memcached

    前言 Memcached 是一个高性能的分布式内存对象缓存系统,其存储性能在某些方面不比redis差,甚至在文本类型数据的存储上性能略优于redis,本文将介绍如何在springboot中集成memc ...

  10. html5 标准文档结构

    <!DOCTYPE html> <html lang="zh-cmn-Hans"> <head> <meta charset=" ...