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

一、准备自定义注解

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

二、实现

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. flask入门(四)

    数据库 flask在数据库这一块有一个扩展应用叫做flask-sqlalchemy,去虚拟环境里pip install一下,如下 我这边用的是mysql,指定的url是这个mysql://userna ...

  2. JS高级---正则表达式练习身份证号码

    写正则表达式, 根据字符串来写正则表达式进行匹配 经验: 1.找规律  2.不要追求完美   身份证的正则表达式 15位或者18位 ([1-9][0-9]{14})|([1-9][0-9]{16}[0 ...

  3. AcWing 278. 数字组合 求方案数目

    //M看成背包容量,把每个数看成一个物品,Ai看成是体积 //目标:求总体积恰好为M的方案数目 #include <iostream> using namespace std; ; int ...

  4. 生成器和迭代器_python

    一.生成器简介(generator) 在进行较大数据的存储,如果直接存储在列表之中,则会可能造成内存的不够与速度的减慢,因为列表创建完是立即创建并存在的,而在python中生成器(generator) ...

  5. 五、抗DDOS防火墙

    简介 DDoS全名是Distribution Denial of service (分布式拒绝服务攻击).拒绝服务攻击的攻击方式有很多种,最基本的Dos攻击就是利用合理的服务请求来占用过多的服务资源, ...

  6. 使用LxRunOffline工具备份/还原Linux子系统(WSL)

    安装WSL 开启WSL组件 首先需要打开WSL组件,可以使用以下命令: Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Win ...

  7. 配置数据库属性validationQuery

    配置数据库时,属性validationQuery默认值为“select 1”,对于oracle值应为“select 1 from dual” validationQuery属性:用来验证数据库连接的语 ...

  8. 微信环境中如何实现跳转到手机默认外部浏览器下载apk文件

    由于微信的限制,应用文件在内置浏览器中下载全部被屏蔽掉,造成很多人用微信扫描二维码下载时点击下载按钮没反应,我想到的是做一个提示用户在浏览器中打开下载.其实原来很简单,就是判断当前是在微信内置浏览器中 ...

  9. Intellij-Idea使用小细节

    SpringMVC项目部署到tomcat中文乱码,tomcat的配置里面加上 -Dfile.encoding=UTF-8

  10. Linux - shell - xargs - 基础

    概述 简述 xargs 的使用 背景 尝试批量操作文件 发现一些问题小问题 然后, 尝试解决 准备 环境 OS centos7 1. 操作: 尝试创建多个 文本文件 概述 尝试创建多个文本文件 1. ...