java註解實現代理
阿新 • • 發佈:2018-09-12
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 importjava.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 */ 23public 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註解實現代理