|
| 1 | +package com.wang.code; |
| 2 | + |
| 3 | +import java.lang.reflect.InvocationHandler; |
| 4 | +import java.lang.reflect.Method; |
| 5 | +import java.lang.reflect.Proxy; |
| 6 | + |
| 7 | +public class ProxyDemo { |
| 8 | + |
| 9 | + public interface Hello { |
| 10 | + void sayHello(); |
| 11 | + } |
| 12 | + public static class HelloImpl implements Hello { |
| 13 | + |
| 14 | + @Override |
| 15 | + public void sayHello(){ |
| 16 | + System.out.println("hello"); |
| 17 | + }; |
| 18 | + } |
| 19 | + |
| 20 | + public static class ProxyHandler implements InvocationHandler{ |
| 21 | + |
| 22 | + public Object object; |
| 23 | + |
| 24 | + public ProxyHandler(Object object){ |
| 25 | + this.object = object; |
| 26 | + } |
| 27 | + |
| 28 | + @Override |
| 29 | + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { |
| 30 | + System.out.println("Before invoke " + method.getName()); |
| 31 | + Object result = method.invoke(object, args); |
| 32 | + System.out.println("After invoke " + method.getName()); |
| 33 | + return result; |
| 34 | + } |
| 35 | + } |
| 36 | + |
| 37 | + public static void main(String[] args) { |
| 38 | + |
| 39 | + /* |
| 40 | + * 首先概念: |
| 41 | + * 强类型:在不同类型的变量赋值时,是否需要显示的类型转换 |
| 42 | + * 静态语言:类型检查是在编译器检查 |
| 43 | + * java呢,是强类型静态语言,但是由于提供了反射等机制,所以具备部分动态语言的特性 |
| 44 | + */ |
| 45 | + |
| 46 | + /* |
| 47 | + * 反射机制 |
| 48 | + * JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法; |
| 49 | + * 对于任意一个对象,都能够调用它的任意方法和属性; |
| 50 | + * 这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。 |
| 51 | + */ |
| 52 | + |
| 53 | + // Class<String> stringClass = String.class; |
| 54 | + // stringClass.get*** |
| 55 | + |
| 56 | + /* |
| 57 | + * 动态代理 |
| 58 | + * 动态代理是利用反射机制在运行时创建代理类 |
| 59 | + * |
| 60 | + * JDK Proxy 的优势: |
| 61 | + * 最小化依赖关系,减少依赖意味着简化开发和维护,JDK 本身的支持,可能比 cglib 更加可靠。 |
| 62 | + * 平滑进行 JDK 版本升级,而字节码类库通常需要进行更新以保证在新版 Java 上能够使用。 |
| 63 | + * 代码实现简单。 |
| 64 | + * |
| 65 | + * 基于类似 cglib 框架的优势: |
| 66 | + * 有的时候调用目标可能不便实现额外接口,从某种角度看,限定调用者实现接口是有些侵入性的实践,类似 cglib 动态代理就没有这种限制。 |
| 67 | + * 只操作我们关心的类,而不必为其他相关类增加工作量。 |
| 68 | + * 高性能。 |
| 69 | + */ |
| 70 | + |
| 71 | + Hello hello = new HelloImpl(); |
| 72 | + InvocationHandler proxyHandler = new ProxyHandler(hello); |
| 73 | + Hello proxyInstance = (Hello) Proxy.newProxyInstance( |
| 74 | + hello.getClass().getClassLoader(), |
| 75 | + hello.getClass().getInterfaces(), |
| 76 | + proxyHandler); |
| 77 | + |
| 78 | + proxyInstance.sayHello(); |
| 79 | + |
| 80 | + /* |
| 81 | + * 动态代理原理: |
| 82 | + * newProxyInstance ——> getProxyClass0获取到class对象 ——> ProxyClassFactor.apply() ——> generateProxyClass() |
| 83 | + * ——> 通过反射获取代理类的构造器 ——> cons.newInstance(new Object[]{h})生成代理类 |
| 84 | + */ |
| 85 | + |
| 86 | + /* |
| 87 | + * 实现动态代理主要的方式: 基于接口的 JDK Proxy、ASM、CGlib(基于ASM)、Javassist |
| 88 | + */ |
| 89 | + |
| 90 | + |
| 91 | + } |
| 92 | +} |
0 commit comments