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

一、准备自定义注解

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

二、实现

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. windows redis启动

    1.下载redis 2.启动redis 3.启动redis客户端并设置protected-mode为false

  2. 02 Django虚拟环境搭建

    01 创建虚拟环境目录 该目录用于存放所有虚拟环境. cd / mkdir venv cd venv 02 创建当前项目的虚拟环境 virtualenv --python=/usr/bin/pytho ...

  3. 【Python】字符串处理函数

  4. K3修改字段名

    在K3的BOS中,自定义字段之后我们往往会修改字段名,便于记忆和理解,但是修改字段名之后,只是数据库中的字段名被修改了,BOS中的字段标识并没有被修改,可以通过以下语句将标识和字段名改成一致. sel ...

  5. java异常处理课后作

    1.动手动脑 源码 import javax.swing.*; class AboutException {   public static void main(String[] a)    {    ...

  6. linq和初始化器

    对象初始化器 在没有初始化器之前,我们初始化一个对象可能需要在构造函数内对属性赋值,或者先实例化一个对象,在一个一个的对其属性赋值. 使用初始化器: 已知类型:var query = new Pers ...

  7. oracle 数据库手动备份和恢复

    一.备份命令: 1.cmd  : exp 2.cmd  :用户名/密码@ip地址/数据库名  如:     yyj/yyj@172.12.5.5/orcl    要导出的数据库 3.回车:输入要输出的 ...

  8. echats--visualmap

    visualmap 既图片左下角的筛选按钮 1.对颜色的区分 visualMap: [ { top: 20, left: 0, right: null, // 设置文本为红色 textStyle: { ...

  9. Java内存管理(1)——垃圾收集

    其它语言(如C语言)要求程序员显式地分配内存.释放内存. 程序需要内存时分配内存,不需要时释放内存. 但是这种做法常常引起内存泄漏.所谓内存泄漏,就是由于某种原因使分配的内存始终没有得到释放.如果该任 ...

  10. 第一篇,VScode插架以及配置项

      由于在开发的时候我们经常因为ESLint规范把自己搞的头晕眼花,修改起来又很浪费时间.所以我特别做个记录,如下代码可以轻松搞的.   工欲善其事必先利器,如果想要在开发的道路上如履平地必须要有得心 ...