代理模式首先可以分为静态代理和动态代理:静态代理指的是在程序编译阶段就将代理类等生成为class对象,程序通过代理对象调用增强方法;动态代理指的是在程序运行阶段通过反射、字节码等技术动态地调用增强方法的实现方式。
区别: 动态代理更加灵活,不需要必须实现接口;静态代理在编译时就将接口、实现类、代理类这些都变成了一个个实际的 class 文件。而动态代理是在运行时动态生成类字节码,并加载到 JVM 中的
静态代理:
用特定的proxy类实现代增强类的代增强方法:
动态代理:
动态代理中代表有JDK动态代理和cglib代理;
JDK代理:
核心实现方法是InvocationHandler接口和Proxy类,
1.自定义一个InvocationHandler来实现InvocationHandler接口的invoke方法作为增强方法,
2.通Proxy.newProxyInstance(ClassLoader loader(类加载器,用于加载代理对象), Class<?>[] interfaces( 被代理类实现的一些接口), InvocationHandler h(实现了 InvocationHandler 接口的对象)) 来获取代理对象。
cglib代理:
(Code Generation Library)是一个基于ASMopen in new window的字节码生成库,它允许我们在运行时对字节码进行修改和动态生成。CGLIB 通过继承方式实现代理。很多知名的开源框架都使用到了CGLIBopen in new window, 例如 Spring 中的 AOP 模块中:如果目标对象实现了接口,则默认采用 JDK 动态代理,否则采用 CGLIB 动态代理。
MethodInterceptor 接口和 Enhancer 类是核心,
1.自定义 MethodInterceptor 并重写 intercept 方法,intercept 用于拦截增强被代理类的方法,和 JDK 动态代理中的 invoke 方法类似;
2.通过 Enhancer 类的 create()创建代理类。
区别:JDK 动态代理只能代理实现了接口的类或者直接代理接口,而 CGLIB 可以代理未实现任何接口的类, CGLIB 动态代理是通过生成一个被代理类的子类来拦截被代理类的方法调用,因此不能代理声明为 final 类型的类和方法