这是最近朋友的一个需求,正好闲来无聊有些时间,跟着研究一下,如有不正确的地方,欢迎大家指正~
一、准备自定义注解
注:如何实现自定义注解,请移步百度。
二、实现
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; }
测试结果如下: