使用注解来实现代理。主要使用三个自定义的类。如下。
一,枚举类,有前后两种。
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 List90 */ 91 public staticproxyMethodList;// 代理的方法集合 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 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 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 *
使用的条件:
代理类继承上边代理基础类,接口对象赋值实现类。实现类添加注解。
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<后>