楼子湾

导航

 

 

一.定义

代理模式(Proxy Pattern): 提供了间接对目标对象的访问方式---即通过代理对象访问目标对象, 代理对象就类似中介

 

 

代理模式分类:静态代理和动态代理,动态代理又分为jdk动态代理和cglib动态代理

二.静态代理

被代理对象和代理对象需要实现相同的接口或者继承相同父类同时代理对象中添加对代理对象接口或者抽象类的引用,故要定义一个借口或者抽象类

示例:

 1 // 接口: 代理对象和被代理对象的共同接口
 2 public interface IStar {
 3     public void sing();
 4 }
 5 
 6 // 具体的被代理对象:谢霆锋唱歌
 7 public class XTFIStar implements IStar {
 8 
 9     @Override
10     public void sing() {
11         System.out.println("谢霆锋唱歌");
12     }
13 }
14 
15 /**
16  *  代理对象: 1.和被代理对象实现相同的接口
17  *  2.持有对被代理对象的引用
18  */
19 public class ProxyManager implements IStar {
20 
21     private IStar iStar;
22     public ProxyManager(IStar iStar) {
23         this.iStar = iStar;
24     }
25 
26     @Override
27     public void sing() {
28         System.out.println("唱歌前准备");
29         iStar.sing();
30         System.out.println("唱歌后分钱");
31     }
32 }
33 
34 // 测试:
35 ProxyManager proxyManager = new ProxyManager(new XTFIStar());
36         proxyManager.sing();

测试结果:通过经纪人找刘德华唱歌

 

 静态代理:

优点:可以在不修改目标对象功能的前提下,对目标功能进行扩展

缺点:因为代理对象和目标对象需要实现相同的接口,所以会有很多代理类,类太多。同时,接口一旦增加方法,目标对象与代理对象都需要维护。

三.动态代理

动态代理的主要特点是能够在程序运行时JVM才为被代理对象生成代理对象

动态代理分为:JDK动态代理和cglib动态代理

1.JDK动态代理是一种接口代理,JDK中生成的代理对象的代理类是Proxy,所在包是java.lang.reflect

使用三个包就可以完成JDK动态代理。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
1)实现InvocationHandle接口;2)匿名内部实现接口通过 new InvocationHandle({重写invoke方法})
 1 // 被代理对象实现的接口
 2 public interface IDog {
 3     void run();
 4     void eat();
 5 }
 6 
 7 // 被代理的具体对象
 8 public class BingliDog implements IDog {
 9     @Override
10     public void run() {
11         System.out.println("宾利狗狗在奔跑");
12     }
13 
14     @Override
15     public void eat() {
16         System.out.println("宾利在吃狗粮");
17     }
18 }
19 
20 // 用于增强的方法
21 public class DogUtils {
22     public static void method1(){
23         System.out.println("大摇大摆的来了");
24     }
25 
26     public static void method2(){
27         System.out.println("大摇大摆的走了");
28     }
29 }
30 // 执行器
31 public class MyInvocationHandle implements InvocationHandler {
32     private Object target;
33 
34     public void setTarget(Object target) {
35         this.target = target;
36     }
37 
38     @Override
39     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
40         DogUtils.method1();
41         Object invoke = method.invoke(target, args);
42         DogUtils.method2();
43         return null;
44     }
45 }
46 
47 // 代理对象工厂
48 public class MyProxyFactory {
49 
50     public static Object getProxy(Object target){
51         MyInvocationHandle myInvocationHandle = new MyInvocationHandle();
52         myInvocationHandle.setTarget(target);
53         Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), myInvocationHandle);
54         return proxy;
55     }
56 }
57 
58 // 测试:
59 IDog proxy = (IDog) MyProxyFactory.getProxy(new BingliDog());
60         proxy.run();
61         proxy.eat();

测试结果:涉及Proxy类,Method, InvocationHandle,被代理的对象必须实现接口

 

 

总结: 代理对象不需要实现接口,被代理的对象一定要实现接口,否则不能实现动态代理

2.cglib代理

上面的静态代理和动态代理都要求目标实现一个接口,然后并不是任何一个对象都实现一个接口。

这时就可以继承目标类以目标类子类的方式实现代理,这种方式就叫cglib代理,也叫做子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展。

使用JDK的动态代理有一个限制,目标类必须实现一个或者多个接口,若想代理没有实现接口的类,就使用cglib代理

 

cglib使用的是第三方jar包:在spring-core中已经有对这两个包的引用,故不用额外对其引用

 cglib包的底层是通过使用字节码处理框架ASM来生产新的java类

与jdk动态代理的区别:第一点可以省略接口;第二点代理工程使用的是 org.springframework.cglib.proxy.enhancer来帮助我们生产对象

 1 // 没有实现接口的类
 2 public class HelloService {
 3     public HelloService() {
 4         System.out.println("HelloService的构造");
 5     }
 6 
 7     final public String sayOthers(String name){
 8         System.out.println("HelloService:sayOthers>>"+name);
 9         return null;
10     }
11 
12     public void sayHello(){
13         System.out.println("HelloService:sayHello");
14     }
15 }
16 
17 // 方法拦截器 
18 public class MyMethodInterceptor implements MethodInterceptor {
19     /**
20      *
21      * @param sub:cglib生产的代理对象
22      * @param method: 被代理对象的方法
23      * @param args: 方法入参
24      * @param methodProxy: 代理方法
25      * @return
26      * @throws Throwable
27      */
28     @Override
29     public Object intercept(Object sub, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
30         System.out.println("执行方法前doSomething...");
31         Object invoke = methodProxy.invokeSuper(sub, args);
32         System.out.println("执行方法后doSomething...");
33         return invoke;
34     }
35 }
36 // 工厂类
37 public class CglibFactory {
38     public static <T> T getProxy(Class<T> clazz, MethodInterceptor myMethodInterceptor){
39         System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"C:\\Users\\wxf\\Desktop");
40         Enhancer enhancer = new Enhancer();
41         enhancer.setSuperclass(clazz);
42         enhancer.setCallback(myMethodInterceptor);
43         return (T) enhancer.create();
44     }
45 }
46 
47 测试:
48 MethodInterceptor methodInterceptor = new MyMethodInterceptor();
49         HelloService proxy = CglibFactory.getProxy(HelloService.class, methodInterceptor);
50         proxy.sayHello();
51         proxy.sayOthers("proxy");

结果:sayOthers 方法被final修饰的不能被cglib代理

 

 

生产的代理class文件

 

 

 

 

 第二个文件反编译结果如下:

  1 package com.design.proxy.cglib;
  2 
  3 import java.lang.reflect.Method;
  4 import org.springframework.cglib.core.ReflectUtils;
  5 import org.springframework.cglib.core.Signature;
  6 import org.springframework.cglib.proxy.Callback;
  7 import org.springframework.cglib.proxy.Factory;
  8 import org.springframework.cglib.proxy.MethodInterceptor;
  9 import org.springframework.cglib.proxy.MethodProxy;
 10 
 11 public class HelloService$$EnhancerByCGLIB$$5cb8654c extends HelloService implements Factory {
 12   private boolean CGLIB$BOUND;
 13   
 14   public static Object CGLIB$FACTORY_DATA;
 15   
 16   private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
 17   
 18   private static final Callback[] CGLIB$STATIC_CALLBACKS;
 19   
 20   private MethodInterceptor CGLIB$CALLBACK_0;
 21   
 22   private static Object CGLIB$CALLBACK_FILTER;
 23   
 24   private static final Method CGLIB$sayHello$0$Method;
 25   
 26   private static final MethodProxy CGLIB$sayHello$0$Proxy;
 27   
 28   private static final Object[] CGLIB$emptyArgs;
 29   
 30   private static final Method CGLIB$equals$1$Method;
 31   
 32   private static final MethodProxy CGLIB$equals$1$Proxy;
 33   
 34   private static final Method CGLIB$toString$2$Method;
 35   
 36   private static final MethodProxy CGLIB$toString$2$Proxy;
 37   
 38   private static final Method CGLIB$hashCode$3$Method;
 39   
 40   private static final MethodProxy CGLIB$hashCode$3$Proxy;
 41   
 42   private static final Method CGLIB$clone$4$Method;
 43   
 44   private static final MethodProxy CGLIB$clone$4$Proxy;
 45   
 46   static void CGLIB$STATICHOOK1() {
 47     CGLIB$THREAD_CALLBACKS = new ThreadLocal();
 48     CGLIB$emptyArgs = new Object[0];
 49     Class<?> clazz1 = Class.forName("com.design.proxy.cglib.HelloService$$EnhancerByCGLIB$$5cb8654c");
 50     Class<?> clazz2;
 51     CGLIB$equals$1$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[0];
 52     CGLIB$equals$1$Proxy = MethodProxy.create(clazz2, clazz1, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$1");
 53     CGLIB$toString$2$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[1];
 54     CGLIB$toString$2$Proxy = MethodProxy.create(clazz2, clazz1, "()Ljava/lang/String;", "toString", "CGLIB$toString$2");
 55     CGLIB$hashCode$3$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[2];
 56     CGLIB$hashCode$3$Proxy = MethodProxy.create(clazz2, clazz1, "()I", "hashCode", "CGLIB$hashCode$3");
 57     CGLIB$clone$4$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[3];
 58     CGLIB$clone$4$Proxy = MethodProxy.create(clazz2, clazz1, "()Ljava/lang/Object;", "clone", "CGLIB$clone$4");
 59     ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods());
 60     CGLIB$sayHello$0$Method = ReflectUtils.findMethods(new String[] { "sayHello", "()V" }, (clazz2 = Class.forName("com.design.proxy.cglib.HelloService")).getDeclaredMethods())[0];
 61     CGLIB$sayHello$0$Proxy = MethodProxy.create(clazz2, clazz1, "()V", "sayHello", "CGLIB$sayHello$0");
 62     ReflectUtils.findMethods(new String[] { "sayHello", "()V" }, (clazz2 = Class.forName("com.design.proxy.cglib.HelloService")).getDeclaredMethods());
 63   }
 64   
 65   final void CGLIB$sayHello$0() {
 66     super.sayHello();
 67   }
 68   
 69   public final void sayHello() {
 70     if (this.CGLIB$CALLBACK_0 == null)
 71       CGLIB$BIND_CALLBACKS(this); 
 72     if (this.CGLIB$CALLBACK_0 != null)
 73       return; 
 74     super.sayHello();
 75   }
 76   
 77   final boolean CGLIB$equals$1(Object paramObject) {
 78     return super.equals(paramObject);
 79   }
 80   
 81   public final boolean equals(Object paramObject) {
 82     if (this.CGLIB$CALLBACK_0 == null)
 83       CGLIB$BIND_CALLBACKS(this); 
 84     if (this.CGLIB$CALLBACK_0 != null) {
 85       this.CGLIB$CALLBACK_0.intercept(this, CGLIB$equals$1$Method, new Object[] { paramObject }, CGLIB$equals$1$Proxy);
 86       return (this.CGLIB$CALLBACK_0.intercept(this, CGLIB$equals$1$Method, new Object[] { paramObject }, CGLIB$equals$1$Proxy) == null) ? false : ((Boolean)this.CGLIB$CALLBACK_0.intercept(this, CGLIB$equals$1$Method, new Object[] { paramObject }, CGLIB$equals$1$Proxy)).booleanValue();
 87     } 
 88     return super.equals(paramObject);
 89   }
 90   
 91   final String CGLIB$toString$2() {
 92     return super.toString();
 93   }
 94   
 95   public final String toString() {
 96     if (this.CGLIB$CALLBACK_0 == null)
 97       CGLIB$BIND_CALLBACKS(this); 
 98     return (this.CGLIB$CALLBACK_0 != null) ? (String)this.CGLIB$CALLBACK_0.intercept(this, CGLIB$toString$2$Method, CGLIB$emptyArgs, CGLIB$toString$2$Proxy) : super.toString();
 99   }
100   
101   final int CGLIB$hashCode$3() {
102     return super.hashCode();
103   }
104   
105   public final int hashCode() {
106     if (this.CGLIB$CALLBACK_0 == null)
107       CGLIB$BIND_CALLBACKS(this); 
108     if (this.CGLIB$CALLBACK_0 != null) {
109       this.CGLIB$CALLBACK_0.intercept(this, CGLIB$hashCode$3$Method, CGLIB$emptyArgs, CGLIB$hashCode$3$Proxy);
110       return (this.CGLIB$CALLBACK_0.intercept(this, CGLIB$hashCode$3$Method, CGLIB$emptyArgs, CGLIB$hashCode$3$Proxy) == null) ? 0 : ((Number)this.CGLIB$CALLBACK_0.intercept(this, CGLIB$hashCode$3$Method, CGLIB$emptyArgs, CGLIB$hashCode$3$Proxy)).intValue();
111     } 
112     return super.hashCode();
113   }
114   
115   final Object CGLIB$clone$4() throws CloneNotSupportedException {
116     return super.clone();
117   }
118   
119   protected final Object clone() throws CloneNotSupportedException {
120     if (this.CGLIB$CALLBACK_0 == null)
121       CGLIB$BIND_CALLBACKS(this); 
122     return (this.CGLIB$CALLBACK_0 != null) ? this.CGLIB$CALLBACK_0.intercept(this, CGLIB$clone$4$Method, CGLIB$emptyArgs, CGLIB$clone$4$Proxy) : super.clone();
123   }
124   
125   public static MethodProxy CGLIB$findMethodProxy(Signature paramSignature) {
126     // Byte code:
127     //   0: aload_0
128     //   1: invokevirtual toString : ()Ljava/lang/String;
129     //   4: dup
130     //   5: invokevirtual hashCode : ()I
131     //   8: lookupswitch default -> 120, -508378822 -> 60, 1535311470 -> 72, 1826985398 -> 84, 1913648695 -> 96, 1984935277 -> 108
132     //   60: ldc 'clone()Ljava/lang/Object;'
133     //   62: invokevirtual equals : (Ljava/lang/Object;)Z
134     //   65: ifeq -> 121
135     //   68: getstatic com/design/proxy/cglib/HelloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$clone$4$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
136     //   71: areturn
137     //   72: ldc 'sayHello()V'
138     //   74: invokevirtual equals : (Ljava/lang/Object;)Z
139     //   77: ifeq -> 121
140     //   80: getstatic com/design/proxy/cglib/HelloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$sayHello$0$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
141     //   83: areturn
142     //   84: ldc 'equals(Ljava/lang/Object;)Z'
143     //   86: invokevirtual equals : (Ljava/lang/Object;)Z
144     //   89: ifeq -> 121
145     //   92: getstatic com/design/proxy/cglib/HelloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$equals$1$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
146     //   95: areturn
147     //   96: ldc 'toString()Ljava/lang/String;'
148     //   98: invokevirtual equals : (Ljava/lang/Object;)Z
149     //   101: ifeq -> 121
150     //   104: getstatic com/design/proxy/cglib/HelloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$toString$2$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
151     //   107: areturn
152     //   108: ldc 'hashCode()I'
153     //   110: invokevirtual equals : (Ljava/lang/Object;)Z
154     //   113: ifeq -> 121
155     //   116: getstatic com/design/proxy/cglib/HelloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$hashCode$3$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
156     //   119: areturn
157     //   120: pop
158     //   121: aconst_null
159     //   122: areturn
160   }
161   
162   public HelloService$$EnhancerByCGLIB$$5cb8654c() {
163     CGLIB$BIND_CALLBACKS(this);
164   }
165   
166   public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] paramArrayOfCallback) {
167     CGLIB$THREAD_CALLBACKS.set(paramArrayOfCallback);
168   }
169   
170   public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] paramArrayOfCallback) {
171     CGLIB$STATIC_CALLBACKS = paramArrayOfCallback;
172   }
173   
174   private static final void CGLIB$BIND_CALLBACKS(Object paramObject) {
175     HelloService$$EnhancerByCGLIB$$5cb8654c helloService$$EnhancerByCGLIB$$5cb8654c = (HelloService$$EnhancerByCGLIB$$5cb8654c)paramObject;
176     if (!helloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$BOUND) {
177       helloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$BOUND = true;
178       if (CGLIB$THREAD_CALLBACKS.get() == null) {
179         CGLIB$THREAD_CALLBACKS.get();
180         if (CGLIB$STATIC_CALLBACKS == null)
181           return; 
182       } 
183       helloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])CGLIB$THREAD_CALLBACKS.get())[0];
184     } 
185   }
186   
187   public Object newInstance(Callback[] paramArrayOfCallback) {
188     CGLIB$SET_THREAD_CALLBACKS(paramArrayOfCallback);
189     CGLIB$SET_THREAD_CALLBACKS(null);
190     return new HelloService$$EnhancerByCGLIB$$5cb8654c();
191   }
192   
193   public Object newInstance(Callback paramCallback) {
194     CGLIB$SET_THREAD_CALLBACKS(new Callback[] { paramCallback });
195     CGLIB$SET_THREAD_CALLBACKS(null);
196     return new HelloService$$EnhancerByCGLIB$$5cb8654c();
197   }
198   
199   public Object newInstance(Class[] paramArrayOfClass, Object[] paramArrayOfObject, Callback[] paramArrayOfCallback) {
200     // Byte code:
201     //   0: aload_3
202     //   1: invokestatic CGLIB$SET_THREAD_CALLBACKS : ([Lorg/springframework/cglib/proxy/Callback;)V
203     //   4: new com/design/proxy/cglib/HelloService$$EnhancerByCGLIB$$5cb8654c
204     //   7: dup
205     //   8: aload_1
206     //   9: dup
207     //   10: arraylength
208     //   11: tableswitch default -> 35, 0 -> 28
209     //   28: pop
210     //   29: invokespecial <init> : ()V
211     //   32: goto -> 49
212     //   35: goto -> 38
213     //   38: pop
214     //   39: new java/lang/IllegalArgumentException
215     //   42: dup
216     //   43: ldc 'Constructor not found'
217     //   45: invokespecial <init> : (Ljava/lang/String;)V
218     //   48: athrow
219     //   49: aconst_null
220     //   50: invokestatic CGLIB$SET_THREAD_CALLBACKS : ([Lorg/springframework/cglib/proxy/Callback;)V
221     //   53: areturn
222   }
223   
224   public Callback getCallback(int paramInt) {
225     CGLIB$BIND_CALLBACKS(this);
226     switch (paramInt) {
227       case 0:
228       
229     } 
230     return null;
231   }
232   
233   public void setCallback(int paramInt, Callback paramCallback) {
234     switch (paramInt) {
235       case 0:
236         this.CGLIB$CALLBACK_0 = (MethodInterceptor)paramCallback;
237         break;
238     } 
239   }
240   
241   public Callback[] getCallbacks() {
242     CGLIB$BIND_CALLBACKS(this);
243     return new Callback[] { (Callback)this.CGLIB$CALLBACK_0 };
244   }
245   
246   public void setCallbacks(Callback[] paramArrayOfCallback) {
247     this.CGLIB$CALLBACK_0 = (MethodInterceptor)paramArrayOfCallback[0];
248   }
249   
250   static {
251     CGLIB$STATICHOOK1();
252   }
253 }
  1 package com.design.proxy.cglib;
  2 
  3 import java.lang.reflect.Method;
  4 import org.springframework.cglib.core.ReflectUtils;
  5 import org.springframework.cglib.core.Signature;
  6 import org.springframework.cglib.proxy.Callback;
  7 import org.springframework.cglib.proxy.Factory;
  8 import org.springframework.cglib.proxy.MethodInterceptor;
  9 import org.springframework.cglib.proxy.MethodProxy;
 10 
 11 public class HelloService$$EnhancerByCGLIB$$5cb8654c extends HelloService implements Factory {
 12   private boolean CGLIB$BOUND;
 13   
 14   public static Object CGLIB$FACTORY_DATA;
 15   
 16   private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
 17   
 18   private static final Callback[] CGLIB$STATIC_CALLBACKS;
 19   
 20   private MethodInterceptor CGLIB$CALLBACK_0;
 21   
 22   private static Object CGLIB$CALLBACK_FILTER;
 23   
 24   private static final Method CGLIB$sayHello$0$Method;
 25   
 26   private static final MethodProxy CGLIB$sayHello$0$Proxy;
 27   
 28   private static final Object[] CGLIB$emptyArgs;
 29   
 30   private static final Method CGLIB$equals$1$Method;
 31   
 32   private static final MethodProxy CGLIB$equals$1$Proxy;
 33   
 34   private static final Method CGLIB$toString$2$Method;
 35   
 36   private static final MethodProxy CGLIB$toString$2$Proxy;
 37   
 38   private static final Method CGLIB$hashCode$3$Method;
 39   
 40   private static final MethodProxy CGLIB$hashCode$3$Proxy;
 41   
 42   private static final Method CGLIB$clone$4$Method;
 43   
 44   private static final MethodProxy CGLIB$clone$4$Proxy;
 45   
 46   static void CGLIB$STATICHOOK1() {
 47     CGLIB$THREAD_CALLBACKS = new ThreadLocal();
 48     CGLIB$emptyArgs = new Object[0];
 49     Class<?> clazz1 = Class.forName("com.design.proxy.cglib.HelloService$$EnhancerByCGLIB$$5cb8654c");
 50     Class<?> clazz2;
 51     CGLIB$equals$1$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[0];
 52     CGLIB$equals$1$Proxy = MethodProxy.create(clazz2, clazz1, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$1");
 53     CGLIB$toString$2$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[1];
 54     CGLIB$toString$2$Proxy = MethodProxy.create(clazz2, clazz1, "()Ljava/lang/String;", "toString", "CGLIB$toString$2");
 55     CGLIB$hashCode$3$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[2];
 56     CGLIB$hashCode$3$Proxy = MethodProxy.create(clazz2, clazz1, "()I", "hashCode", "CGLIB$hashCode$3");
 57     CGLIB$clone$4$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[3];
 58     CGLIB$clone$4$Proxy = MethodProxy.create(clazz2, clazz1, "()Ljava/lang/Object;", "clone", "CGLIB$clone$4");
 59     ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods());
 60     CGLIB$sayHello$0$Method = ReflectUtils.findMethods(new String[] { "sayHello", "()V" }, (clazz2 = Class.forName("com.design.proxy.cglib.HelloService")).getDeclaredMethods())[0];
 61     CGLIB$sayHello$0$Proxy = MethodProxy.create(clazz2, clazz1, "()V", "sayHello", "CGLIB$sayHello$0");
 62     ReflectUtils.findMethods(new String[] { "sayHello", "()V" }, (clazz2 = Class.forName("com.design.proxy.cglib.HelloService")).getDeclaredMethods());
 63   }
 64   
 65   final void CGLIB$sayHello$0() {
 66     super.sayHello();
 67   }
 68   
 69   public final void sayHello() {
 70     if (this.CGLIB$CALLBACK_0 == null)
 71       CGLIB$BIND_CALLBACKS(this); 
 72     if (this.CGLIB$CALLBACK_0 != null)
 73       return; 
 74     super.sayHello();
 75   }
 76   
 77   final boolean CGLIB$equals$1(Object paramObject) {
 78     return super.equals(paramObject);
 79   }
 80   
 81   public final boolean equals(Object paramObject) {
 82     if (this.CGLIB$CALLBACK_0 == null)
 83       CGLIB$BIND_CALLBACKS(this); 
 84     if (this.CGLIB$CALLBACK_0 != null) {
 85       this.CGLIB$CALLBACK_0.intercept(this, CGLIB$equals$1$Method, new Object[] { paramObject }, CGLIB$equals$1$Proxy);
 86       return (this.CGLIB$CALLBACK_0.intercept(this, CGLIB$equals$1$Method, new Object[] { paramObject }, CGLIB$equals$1$Proxy) == null) ? false : ((Boolean)this.CGLIB$CALLBACK_0.intercept(this, CGLIB$equals$1$Method, new Object[] { paramObject }, CGLIB$equals$1$Proxy)).booleanValue();
 87     } 
 88     return super.equals(paramObject);
 89   }
 90   
 91   final String CGLIB$toString$2() {
 92     return super.toString();
 93   }
 94   
 95   public final String toString() {
 96     if (this.CGLIB$CALLBACK_0 == null)
 97       CGLIB$BIND_CALLBACKS(this); 
 98     return (this.CGLIB$CALLBACK_0 != null) ? (String)this.CGLIB$CALLBACK_0.intercept(this, CGLIB$toString$2$Method, CGLIB$emptyArgs, CGLIB$toString$2$Proxy) : super.toString();
 99   }
100   
101   final int CGLIB$hashCode$3() {
102     return super.hashCode();
103   }
104   
105   public final int hashCode() {
106     if (this.CGLIB$CALLBACK_0 == null)
107       CGLIB$BIND_CALLBACKS(this); 
108     if (this.CGLIB$CALLBACK_0 != null) {
109       this.CGLIB$CALLBACK_0.intercept(this, CGLIB$hashCode$3$Method, CGLIB$emptyArgs, CGLIB$hashCode$3$Proxy);
110       return (this.CGLIB$CALLBACK_0.intercept(this, CGLIB$hashCode$3$Method, CGLIB$emptyArgs, CGLIB$hashCode$3$Proxy) == null) ? 0 : ((Number)this.CGLIB$CALLBACK_0.intercept(this, CGLIB$hashCode$3$Method, CGLIB$emptyArgs, CGLIB$hashCode$3$Proxy)).intValue();
111     } 
112     return super.hashCode();
113   }
114   
115   final Object CGLIB$clone$4() throws CloneNotSupportedException {
116     return super.clone();
117   }
118   
119   protected final Object clone() throws CloneNotSupportedException {
120     if (this.CGLIB$CALLBACK_0 == null)
121       CGLIB$BIND_CALLBACKS(this); 
122     return (this.CGLIB$CALLBACK_0 != null) ? this.CGLIB$CALLBACK_0.intercept(this, CGLIB$clone$4$Method, CGLIB$emptyArgs, CGLIB$clone$4$Proxy) : super.clone();
123   }
124   
125   public static MethodProxy CGLIB$findMethodProxy(Signature paramSignature) {
126     // Byte code:
127     //   0: aload_0
128     //   1: invokevirtual toString : ()Ljava/lang/String;
129     //   4: dup
130     //   5: invokevirtual hashCode : ()I
131     //   8: lookupswitch default -> 120, -508378822 -> 60, 1535311470 -> 72, 1826985398 -> 84, 1913648695 -> 96, 1984935277 -> 108
132     //   60: ldc 'clone()Ljava/lang/Object;'
133     //   62: invokevirtual equals : (Ljava/lang/Object;)Z
134     //   65: ifeq -> 121
135     //   68: getstatic com/design/proxy/cglib/HelloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$clone$4$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
136     //   71: areturn
137     //   72: ldc 'sayHello()V'
138     //   74: invokevirtual equals : (Ljava/lang/Object;)Z
139     //   77: ifeq -> 121
140     //   80: getstatic com/design/proxy/cglib/HelloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$sayHello$0$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
141     //   83: areturn
142     //   84: ldc 'equals(Ljava/lang/Object;)Z'
143     //   86: invokevirtual equals : (Ljava/lang/Object;)Z
144     //   89: ifeq -> 121
145     //   92: getstatic com/design/proxy/cglib/HelloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$equals$1$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
146     //   95: areturn
147     //   96: ldc 'toString()Ljava/lang/String;'
148     //   98: invokevirtual equals : (Ljava/lang/Object;)Z
149     //   101: ifeq -> 121
150     //   104: getstatic com/design/proxy/cglib/HelloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$toString$2$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
151     //   107: areturn
152     //   108: ldc 'hashCode()I'
153     //   110: invokevirtual equals : (Ljava/lang/Object;)Z
154     //   113: ifeq -> 121
155     //   116: getstatic com/design/proxy/cglib/HelloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$hashCode$3$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
156     //   119: areturn
157     //   120: pop
158     //   121: aconst_null
159     //   122: areturn
160   }
161   
162   public HelloService$$EnhancerByCGLIB$$5cb8654c() {
163     CGLIB$BIND_CALLBACKS(this);
164   }
165   
166   public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] paramArrayOfCallback) {
167     CGLIB$THREAD_CALLBACKS.set(paramArrayOfCallback);
168   }
169   
170   public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] paramArrayOfCallback) {
171     CGLIB$STATIC_CALLBACKS = paramArrayOfCallback;
172   }
173   
174   private static final void CGLIB$BIND_CALLBACKS(Object paramObject) {
175     HelloService$$EnhancerByCGLIB$$5cb8654c helloService$$EnhancerByCGLIB$$5cb8654c = (HelloService$$EnhancerByCGLIB$$5cb8654c)paramObject;
176     if (!helloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$BOUND) {
177       helloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$BOUND = true;
178       if (CGLIB$THREAD_CALLBACKS.get() == null) {
179         CGLIB$THREAD_CALLBACKS.get();
180         if (CGLIB$STATIC_CALLBACKS == null)
181           return; 
182       } 
183       helloService$$EnhancerByCGLIB$$5cb8654c.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])CGLIB$THREAD_CALLBACKS.get())[0];
184     } 
185   }
186   
187   public Object newInstance(Callback[] paramArrayOfCallback) {
188     CGLIB$SET_THREAD_CALLBACKS(paramArrayOfCallback);
189     CGLIB$SET_THREAD_CALLBACKS(null);
190     return new HelloService$$EnhancerByCGLIB$$5cb8654c();
191   }
192   
193   public Object newInstance(Callback paramCallback) {
194     CGLIB$SET_THREAD_CALLBACKS(new Callback[] { paramCallback });
195     CGLIB$SET_THREAD_CALLBACKS(null);
196     return new HelloService$$EnhancerByCGLIB$$5cb8654c();
197   }
198   
199   public Object newInstance(Class[] paramArrayOfClass, Object[] paramArrayOfObject, Callback[] paramArrayOfCallback) {
200     // Byte code:
201     //   0: aload_3
202     //   1: invokestatic CGLIB$SET_THREAD_CALLBACKS : ([Lorg/springframework/cglib/proxy/Callback;)V
203     //   4: new com/design/proxy/cglib/HelloService$$EnhancerByCGLIB$$5cb8654c
204     //   7: dup
205     //   8: aload_1
206     //   9: dup
207     //   10: arraylength
208     //   11: tableswitch default -> 35, 0 -> 28
209     //   28: pop
210     //   29: invokespecial <init> : ()V
211     //   32: goto -> 49
212     //   35: goto -> 38
213     //   38: pop
214     //   39: new java/lang/IllegalArgumentException
215     //   42: dup
216     //   43: ldc 'Constructor not found'
217     //   45: invokespecial <init> : (Ljava/lang/String;)V
218     //   48: athrow
219     //   49: aconst_null
220     //   50: invokestatic CGLIB$SET_THREAD_CALLBACKS : ([Lorg/springframework/cglib/proxy/Callback;)V
221     //   53: areturn
222   }
223   
224   public Callback getCallback(int paramInt) {
225     CGLIB$BIND_CALLBACKS(this);
226     switch (paramInt) {
227       case 0:
228       
229     } 
230     return null;
231   }
232   
233   public void setCallback(int paramInt, Callback paramCallback) {
234     switch (paramInt) {
235       case 0:
236         this.CGLIB$CALLBACK_0 = (MethodInterceptor)paramCallback;
237         break;
238     } 
239   }
240   
241   public Callback[] getCallbacks() {
242     CGLIB$BIND_CALLBACKS(this);
243     return new Callback[] { (Callback)this.CGLIB$CALLBACK_0 };
244   }
245   
246   public void setCallbacks(Callback[] paramArrayOfCallback) {
247     this.CGLIB$CALLBACK_0 = (MethodInterceptor)paramArrayOfCallback[0];
248   }
249   
250   static {
251     CGLIB$STATICHOOK1();
252   }
253 }

重点关注代理对象的sayHello方法

 从代理对象的反编译源码可以看出来,代理对象继承于HelloService, 拦截器调用intercept()方法,最终是调用拦截器的intercept方法,完成由代理对象访问目标对象的动态代理实现

总结:

静态代理需要手动编写代理类 和目标方法

JDK动态代理不需要手动编写代理类和目标方法,但是JDK动态代理必须要实现接口

CGLIB动态代理可以实现接口也已不实现, 因为可以使用继承子类的方式处理

 

posted on 2020-05-08 22:17  楼子湾  阅读(250)  评论(0编辑  收藏  举报