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

 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值