1. 程式人生 > >java註解實現代理

java註解實現代理

inter vat parse system urn lan run ppr eth

使用註解來實現代理。主要使用三個自定義的類。如下。

一,枚舉類,有前後兩種。

 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<後>

java註解實現代理