标签:false not -- and target on() handler 枚举 ring
使用注解来实现代理。主要使用三个自定义的类。如下。
一,枚举类,有前后两种。
1 package cn.jxlys.util; 2 3 /** 4 * 代理的类型,前还是后 5 * 6 * @author jxlys 7 * 8 */ 9 public enum ProxyType { 10 BEFORE(ProxyBase.BEFORE_STRING), AFTER(ProxyBase.AFTER_STRING); 11 public String value; 12 13 private ProxyType(String value) { 14 this.value = value; 15 } 16 17 }
二,注解类。
1 package cn.jxlys.util; 2 3 import static cn.jxlys.util.ProxyType.*; 4 import static java.lang.annotation.ElementType.METHOD; 5 import static java.lang.annotation.ElementType.TYPE; 6 7 import java.lang.annotation.Retention; 8 import java.lang.annotation.RetentionPolicy; 9 import java.lang.annotation.Target; 10 11 /** 12 * 自定义的注解代理对象:必须是接口对象赋值实现类 13 * 14 * @author jxlys 15 */ 16 @Retention(RetentionPolicy.RUNTIME) 17 @Target(value = { TYPE, METHOD }) 18 public @interface JsProxy { 19 20 /** 21 * 设置代理对象的类 22 */ 23 public Class<?> value(); 24 25 /** 26 * 设置拦截的类型,默认前后拦截 27 */ 28 public ProxyType[] type() default { AFTER, BEFORE }; 29 30 }
三,代理类的基础类,用来被继承并且获得代理对象。
1 package cn.jxlys.util; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.InvocationTargetException; 5 import java.lang.reflect.Method; 6 import java.lang.reflect.Proxy; 7 import java.util.ArrayList; 8 import java.util.Arrays; 9 import java.util.List; 10 11 /** 12 * 代理类的基础,必须先是设置对象(必须是接口对象赋值实现类),不然获取的代理对象会空指针。 13 * 14 * @author jxlys 15 * 16 */ 17 public class ProxyBase implements InvocationHandler { 18 public static final String BEFORE_STRING = "before"; 19 public static final String AFTER_STRING = "after"; 20 // 是否代理所有方法 21 private boolean isAllProxy = false; 22 // 被代理对象 23 private Object srcObj; 24 // 具体代理的方法集合 25 private List<Method> proxyMethodList;// 代理的方法集合 26 27 static class ProxyHelp { 28 private static final Class<JsProxy> JsProxy = JsProxy.class; 29 30 @SuppressWarnings("unchecked") 31 // 强转对象 32 public static <T> T parseObject(Object srcObj, Class<T> srcClass) { 33 return (T) srcObj; 34 } 35 36 // 获取代理对象,或是原生对象 37 public static <T> T getInstance(T srcObj) { 38 T resultObject = null; 39 Class<? extends Object> tclass = srcObj.getClass(); 40 if (tclass.getAnnotation(ProxyHelp.JsProxy) != null) { 41 resultObject = trySetProxy(srcObj, Arrays.asList(tclass.getMethods()), tclass.getAnnotation(ProxyHelp.JsProxy), true); 42 if (resultObject != null) { 43 return resultObject; 44 } 45 } 46 Method[] methods = srcObj.getClass().getMethods(); 47 List<Method> methodList = new ArrayList<>(); 48 JsProxy myproxy = null; 49 for (Method tempMethod : methods) { 50 if (tempMethod.getAnnotation(ProxyHelp.JsProxy) != null) { 51 if (myproxy == null) { 52 myproxy = tempMethod.getAnnotation(ProxyHelp.JsProxy); 53 } 54 if (myproxy.annotationType().getName().equals(tempMethod.getAnnotation(ProxyHelp.JsProxy).annotationType().getName())) { 55 methodList.add(tempMethod); 56 } 57 } 58 } 59 resultObject = trySetProxy(srcObj, methodList, myproxy, false); 60 if (resultObject != null) { 61 return resultObject; 62 } 63 return srcObj; 64 } 65 66 // 尝试获取代理 67 @SuppressWarnings("unchecked") 68 private static <T> T trySetProxy(T srcObj, List<Method> methodList, JsProxy myproxy, boolean isClassAnno) { 69 try { 70 Object proxyObj = myproxy.value().newInstance(); 71 if (proxyObj instanceof ProxyBase) { 72 ProxyBase proxyBase = (ProxyBase) proxyObj; 73 proxyBase.srcObj = srcObj; 74 proxyBase.isAllProxy = isClassAnno; 75 proxyBase.proxyMethodList = methodList; 76 Object tempObj = Proxy.newProxyInstance(srcObj.getClass().getClassLoader(), srcObj.getClass().getInterfaces(), proxyBase); 77 return (T) tempObj;// 代理对象必然能够强转 78 } 79 } catch (InstantiationException | IllegalAccessException e) { 80 } 81 return null; 82 } 83 } 84 85 /** 86 * <Pre> 87 * 获取对象的代理:对象必须是接口对象,注解必须是ProxyBase的子类 88 * java.lang.ClassCastException:错误则是对象不能转化为 89 * </pre> 90 */ 91 public static <T> T getInstance(T t) { 92 return ProxyHelp.getInstance(t); 93 } 94 95 public ProxyBase() { 96 } 97 98 /** 99 * 重写的方法 100 */ 101 public void afterAction() { 102 } 103 104 /** 105 * 重写的方法 106 */ 107 public void beforeAction() { 108 } 109 110 private Method getMethod(List<Method> proxyMethod2, Method method) { 111 for (Method m : proxyMethod2) { 112 if (m.getName().equals(method.getName())) {// 比较参数是否一一对应 113 Class<?>[] paramTypes1 = m.getParameterTypes(); 114 Class<?>[] paramTypes2 = method.getParameterTypes(); 115 if (paramTypes1.length == paramTypes2.length && paramTypes1.length == 0) { 116 return m; 117 } else if (paramTypes1.length == paramTypes2.length) { 118 for (int i = 0; i < paramTypes2.length; i++) { 119 if (paramTypes1[i] == paramTypes2[i]) { 120 return null; 121 } 122 if (i == paramTypes2.length - 1) { 123 return m; 124 } 125 } 126 } 127 } 128 } 129 return null; 130 } 131 132 /** 133 * 用来获取被代理对象,用来强转,使用请注意类型。 134 */ 135 public <T> T getObj(Class<T> t) { 136 return ProxyHelp.parseObject(srcObj, t); 137 } 138 139 // 代理 140 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 141 if (isAllProxy) { 142 JsProxy myProxy = srcObj.getClass().getAnnotation(ProxyHelp.JsProxy); 143 return runInvoke(method, args, myProxy); 144 } else { 145 Method tempMethod = getMethod(proxyMethodList, method); 146 if (tempMethod != null) { 147 return runInvoke(method, args, tempMethod.getAnnotation(ProxyHelp.JsProxy)); 148 } else { 149 return method.invoke(srcObj, args); 150 } 151 } 152 } 153 154 private Object runInvoke(Method method, Object[] args, JsProxy myProxy) throws IllegalAccessException, InvocationTargetException { 155 Object resultObj; 156 if (myProxy != null) { 157 ProxyType[] proxyLocation = myProxy.type(); 158 for (ProxyType proxyType : proxyLocation) { 159 if (AFTER_STRING.equals(proxyType.value)) { 160 beforeAction(); 161 } 162 } 163 resultObj = method.invoke(srcObj, args); 164 for (ProxyType proxyType : proxyLocation) { 165 if (BEFORE_STRING.equals(proxyType.value)) { 166 afterAction(); 167 } 168 } 169 } else { 170 resultObj = method.invoke(srcObj, args); 171 } 172 return resultObj; 173 } 174 175 }
使用的条件:
代理类继承上边代理基础类,接口对象赋值实现类。实现类添加注解。
1 //代理的实现类 2 class ProxyA extends ProxyBase { 3 public void beforeAction() { 4 System.out.print("<前>"); 5 } 6 7 public void afterAction() { 8 System.out.print("<后>"); 9 } 10 } 11 //接口 12 interface A { 13 void say1(); 14 15 void say2(); 16 }
实现类
1 // @JsProxy(ProxyA.class) 放在类上,代理所有方法,前后执行代理 2 // @JsProxy(value = ProxyA.class, type = { ProxyType.BEFORE, ProxyType.AFTER }) 3 // //放在类上,代理所有方法,可选择部分执行 4 class B implements A { 5 // @JsProxy( ProxyA.class) 6 @JsProxy(value = ProxyA.class, type = { ProxyType.BEFORE }) 7 public void say1() { 8 System.out.print("b1"); 9 } 10 11 @JsProxy(value = ProxyA.class, type = { ProxyType.AFTER }) 12 public void say2() { 13 System.out.print("b2"); 14 } 15 } 16 17 @JsProxy(value = ProxyA.class, type = { ProxyType.BEFORE, ProxyType.AFTER }) 18 class C implements A { 19 public void say1() { 20 System.out.print("c1"); 21 } 22 23 public void say2() { 24 System.out.print("c2"); 25 } 26 }
调用:
1 public class TestMain { 2 3 public static void showA(String srcShowString, A srcObj) { 4 System.out.println("----------------" + srcShowString + "代理中-----------"); 5 srcObj = ProxyBase.getInstance(srcObj); 6 srcObj.say1(); 7 System.out.println(); 8 srcObj.say2(); 9 System.out.println(); 10 } 11 12 public static void main(String[] args) { 13 A a = new B(); 14 showA("B", a); 15 a = new C(); 16 showA("C", a); 17 } 18 }
效果:
----------------B代理中-----------
b1<后>
<前>b2
----------------C代理中-----------
<前>c1<后>
<前>c2<后>
标签:false not -- and target on() handler 枚举 ring
原文地址:https://www.cnblogs.com/jxlys/p/9636285.html