java注解实现代理

使用注解来实现代理。主要使用三个自定义的类。如下。

一,枚举类,有前后两种。

 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 proxyMethodList;// 代理的方法集合
 26 
 27     static class ProxyHelp {
 28         private static final Class JsProxy = JsProxy.class;
 29 
 30         @SuppressWarnings("unchecked")
 31         // 强转对象
 32         public static  T parseObject(Object srcObj, Class srcClass) {
 33             return (T) srcObj;
 34         }
 35 
 36         // 获取代理对象,或是原生对象
 37         public static  T getInstance(T srcObj) {
 38             T resultObject = null;
 39             Classextends 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 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 trySetProxy(T srcObj, List 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      * 
 87      * 获取对象的代理:对象必须是接口对象,注解必须是ProxyBase的子类
 88      * java.lang.ClassCastException:错误则是对象不能转化为
 89      * 
90 */ 91 public static 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 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 getObj(Class 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<后>

 

转载于:https://www.cnblogs.com/jxlys/p/9636285.html

你可能感兴趣的:(java注解实现代理)