参考
https://blog.csdn.net/lan12334321234/article/details/70048780
基于接口代理「JDK」
基于 JDK 实现动态代理,通过 jdk 提供的工具方法 Proxy.newProxyInstance 动态构建全新的代理类 (继承 Proxy 类,并持有 InvocationHandler 接口引用) 字节码文件并实例化对象返回。(jdk 动态代理是由 java 内部的反射机制来实例化代理对象,并代理的调用委托类方法)
缺点:代理的类必须实现接口,如果没有实现接口,则不能使用 JDK 代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;
interface BookInterface { void addBook(); void intercept(); }; public class BookImpl implements BookInterface { public void addBook() { System.out.println("dynamic@BookImpl#addBook"); } public void intercept() { System.out.println("dynamic@BookImpl#intercept is intercepted..."); } public static void main(String[] args) { BookProxy proxy = new BookProxy(); BookInterface impl = (BookInterface) proxy.getInstance(new BookImpl()); impl.intercept(); } };
class BookProxy implements InvocationHandler {
private Object target; public Object getInstance(Object target) { this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } public Object invoke(Object obj, Method method, Object[] args) throws Throwable { System.out.println("Before Advice"); if ("intercept".equals(method.getName())) { System.out.println("intercept method is intercepted"); return null; } Object result = method.invoke(target, args); System.out.println("After Advice"); return result; } }
|
Cglib 动态代理「生成子类」
cglib 是针对类来实现代理的,他的原理是对指定的目标类生成一个子类, 并覆盖其中方法实现增强,但因为采用的是继承,所以不能对 final 修饰的类进行代理。cglib 动态代理底层则是借助 asm 来实现的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class BookClass {
public void addBook() { System.out.println("cglib@BookClass#addBook"); } public static void main(String[] args) { BookProxy proxy = new BookProxy(); BookClass bc = (BookClass) proxy.getInstance(new BookClass()); bc.addBook(); } };
class BookProxy implements MethodInterceptor {
private Object target; public Object getInstance(Object target) { this.target = target; Enhancer en = new Enhancer(); en.setSuperclass(target.getClass()); en.setCallback(this); return en.create(); } public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("Before Advice"); Object result = proxy.invoke(target, args); System.out.println("After Advice"); return result; } }
|
基于 Aspectj 实现动态代理「编译时插入」
修改目标类的字节,织入代理的字节,在程序编译的时候 插入动态代理的字节码,不会生成全新的 Class
基于 instrumentation 实现动态代理「类装载时插入」
修改目标类的字节码、类装载的时候动态拦截去修改,基于 javaagent) -javaagent:spring-instrument-4.3.8.RELEASE.jar
(类装载的时候 插入动态代理的字节码,不会生成全新的 Class