Spring进阶(AOP基于jdk与cglib实现)

发布时间:2026/9/2 8:56:05
Spring进阶(AOP基于jdk与cglib实现) jdk动态代理的实现特点只能针对接口进行代理是在程序运行期间直接生成字节码不生成源码public class JdkProxyDemo { interface Foo { void foo(); } static class Target implements Foo {//也可以直接加上final public void foo() { System.out.println(target foo); } } // jdk 只能针对接口代理 // cglib public static void main(String[] param) throws IOException { // 目标对象 Target target new Target(); ClassLoader loader JdkProxyDemo.class.getClassLoader(); // 用来加载在运行期间动态生成的字节码 Foo proxy (Foo) Proxy.newProxyInstance(loader, new Class[]{Foo.class}, (p, method, args) - { System.out.println(before...); // 目标.方法(参数) // 方法.invoke(目标, 参数); Object result method.invoke(target, args); System.out.println(after....); return result; // 让代理也返回目标方法执行的结果 }); System.out.println(proxy.getClass()); proxy.foo(); } }Proxy.newProxyInstance参数说明1.生成的字节码必须通过加载后才能运行JVM的运行程序顺序通过ClassLoader实现2.实现要代理的接口3.实现接口的方法模拟jdk动态代理第一版1.准备接口以及实现接口的目标类interface Foo { void foo(); } //目标类 static class Target implements Foo { public void foo() { System.out.println(target foo); } }2.编写代理类public class $Proxy1 implements A12.Foo { Override public void foo() { System.out.println(before...); new A12.Target().foo(); } }3.通过代理类调用方法Foo proxy1 new $Proxy1(); proxy1.foo();第二版1.准备接口以及实现接口的目标类为了解耦新增一个InvocationHandler接口interface Foo { void foo() throws Throwable; } static class Target implements Foo { public void foo() { System.out.println(target foo); } } interface InvocationHandler { Object invoke() throws Throwable; }2.编写代理类public class $Proxy1 implements Foo { private A12.InvocationHandler h; public $Proxy1(InvocationHandler h) { this.h h; } Override public void foo() throws Throwable { h.invoke(); } }3.通过代理类调用方法Foo proxy1 new $Proxy1(new InvocationHandler() { Override public Object invoke() throws Throwable { System.out.println(before...); new Target().foo(); return null; } }); proxy1.foo();第三版1.准备接口以及实现接口的目标类为了更加全面在接口处新增一个方法interface Foo { void foo() throws Throwable; void bar() throws Throwable; } static class Target implements Foo { Override public void foo() { System.out.println(target foo); } Override public void bar() { System.out.println(target bar); } } interface InvocationHandler { Object invoke(Method method,Object[] args) throws Throwable; }2.编写代理类public class $Proxy1 implements A12.Foo { private A12.InvocationHandler h; public $Proxy1(A12.InvocationHandler h) { this.h h; } Override public void foo() throws Throwable { Method foo A12.Foo.class.getDeclaredMethod(foo); h.invoke(foo,new Object[0]); } Override public void bar() throws Throwable { Method bar A12.Foo.class.getDeclaredMethod(bar); h.invoke(bar,new Object[0]); } }3.通过代理类调用方法Foo proxy1 new $Proxy1(new InvocationHandler() { Override public Object invoke(Method method,Object[] args) throws Throwable { System.out.println(before...); method.invoke(new Target(),args); return null; } }); proxy1.foo(); proxy1.bar();第四版1.准备接口以及实现接口的目标类为了更加全面在接口处新增一个方法并带有返回值interface Foo { void foo(); int bar(); } static class Target implements Foo { Override public void foo() { System.out.println(target foo); } Override public int bar() { System.out.println(target bar); return 100; } }public class $Proxy1 implements A12.Foo { private final A12.InvocationHandler h; public $Proxy1(A12.InvocationHandler h) { this.h h; } Override public void foo() { try { h.invoke(this,bar,new Object[0]); } catch (Throwable e) { throw new RuntimeException(e); } } Override public int bar() { try { return (int)h.invoke(this,bar,new Object[0]); } catch (Throwable e) { throw new RuntimeException(e); } } static Method foo; static Method bar; static { try { foo A12.Foo.class.getDeclaredMethod(foo); bar A12.Foo.class.getDeclaredMethod(bar); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } }Foo proxy1 new $Proxy1(new InvocationHandler() { Override public Object invoke(Object proxy,Method method,Object[] args) throws Throwable { System.out.println(before...); Object invoke method.invoke(new Target(), args); return invoke; } }); proxy1.foo(); System.out.println(proxy1.bar());终极版1.准备接口以及实现接口的目标类为了更加全面在接口处新增一个方法并带有返回值与参数并且InvocationHandler采用JDK提供的interface Foo { void foo(); int bar(int num); } static class Target implements Foo { Override public void foo() { System.out.println(target foo); } Override public int bar(int num) { System.out.println(target bar); return num; } }import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class $Proxy1 implements A12.Foo { private final InvocationHandler h; public $Proxy1(InvocationHandler h) { this.h h; } Override public void foo() { try { h.invoke(this,foo,new Object[0]); } catch (Throwable e) { throw new RuntimeException(e); } } Override public int bar(int num) { try { return (int)h.invoke(this,bar,new Object[]{num}); } catch (Throwable e) { throw new RuntimeException(e); } } static Method foo; static Method bar; static { try { foo A12.Foo.class.getDeclaredMethod(foo); bar A12.Foo.class.getDeclaredMethod(bar,int.class); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } }Foo proxy1 new $Proxy1(new InvocationHandler() { Override public Object invoke(Object proxy,Method method,Object[] args) throws Throwable { System.out.println(before...); Object invoke method.invoke(new Target(), args); return invoke; } }); proxy1.foo(); System.out.println(proxy1.bar(120));当然JDK对于反射调用做了一些优化如果调用次数过多会变成正常的调用一般17次。cglib代理实现特点是通过父子继承关系进行代理是在程序运行期间直接生成字节码不生成源码Enhancer.create参数说明1.目标类2.实现接口的方法public class CglibProxyDemo { static class Target { public void foo() { System.out.println(target foo); } } // 代理是子类型, 目标是父类型 public static void main(String[] param) { // Target target new Target(); Target proxy (Target) Enhancer.create(Target.class, (MethodInterceptor) (p, method, args, methodProxy) - { System.out.println(before...); // Object result method.invoke(target, args); // 用方法反射调用目标 // methodProxy 它可以避免反射调用 // Object result methodProxy.invoke(target, args); // 内部没有用反射, 需要目标 spring Object result methodProxy.invokeSuper(p, args); // 内部没有用反射, 需要代理 System.out.println(after...); return result; }); proxy.foo(); } }MethodInterceptor参数说明p:代理对象自身method目标方法需要传入目标类用到反射args方法参数methodProxy代理实现的方法需要传入目标类或者代理类既可以用反射也可以不用注意目标类一定不能是final修饰因为代理类需要继承目标类模拟cglib代理第一版1.准备目标类以及实现的方法public class Target { public void save() { System.out.println(save()); } public void save(int i) { System.out.println(save(int)); } public void save(long j) { System.out.println(save(long)); } }public class Proxy extends Target { //类似于InvocationHandler private MethodInterceptor methodInterceptor; public void setMethodInterceptor(MethodInterceptor methodInterceptor) { this.methodInterceptor methodInterceptor; } static Method save0; static Method save1; static Method save2; static { try { save0 Target.class.getMethod(save); save1 Target.class.getMethod(save, int.class); save2 Target.class.getMethod(save, long.class); } catch (NoSuchMethodException e) { throw new NoSuchMethodError(e.getMessage()); } } // 带增强功能的方法 Override public void save() { try { methodInterceptor.intercept(this, save0, new Object[0], null); } catch (Throwable e) { throw new UndeclaredThrowableException(e); } } Override public void save(int i) { try { methodInterceptor.intercept(this, save1, new Object[]{i}, null); } catch (Throwable e) { throw new UndeclaredThrowableException(e); } } Override public void save(long j) { try { methodInterceptor.intercept(this, save2, new Object[]{j}, null); } catch (Throwable e) { throw new UndeclaredThrowableException(e); } } }3.通过代理类调用方法public static void main(String[] args) { Proxy proxy new Proxy(); Target target new Target(); proxy.setMethodInterceptor(new MethodInterceptor() { Override public Object intercept(Object p, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println(before...); return method.invoke(target, args); // 反射调用 } }); proxy.save(); proxy.save(1); proxy.save(2L); }第二版利用MethodProxy避免反射调用public class Proxy extends Target { private MethodInterceptor methodInterceptor; public void setMethodInterceptor(MethodInterceptor methodInterceptor) { this.methodInterceptor methodInterceptor; } static Method save0; static Method save1; static Method save2; static MethodProxy save0Proxy; static MethodProxy save1Proxy; static MethodProxy save2Proxy; static { try { save0 Target.class.getMethod(save); save1 Target.class.getMethod(save, int.class); save2 Target.class.getMethod(save, long.class); save0Proxy MethodProxy.create(Target.class, Proxy.class, ()V, save, saveSuper); save1Proxy MethodProxy.create(Target.class, Proxy.class, (I)V, save, saveSuper); save2Proxy MethodProxy.create(Target.class, Proxy.class, (J)V, save, saveSuper); } catch (NoSuchMethodException e) { throw new NoSuchMethodError(e.getMessage()); } } // 带原始功能的方法 public void saveSuper() { super.save(); } public void saveSuper(int i) { super.save(i); } public void saveSuper(long j) { super.save(j); } // 带增强功能的方法 Override public void save() { try { methodInterceptor.intercept(this, save0, new Object[0], save0Proxy); } catch (Throwable e) { throw new UndeclaredThrowableException(e); } } Override public void save(int i) { try { methodInterceptor.intercept(this, save1, new Object[]{i}, save1Proxy); } catch (Throwable e) { throw new UndeclaredThrowableException(e); } } Override public void save(long j) { try { methodInterceptor.intercept(this, save2, new Object[]{j}, save2Proxy); } catch (Throwable e) { throw new UndeclaredThrowableException(e); } } }通过无反射类调用方法public static void main(String[] args) { Proxy proxy new Proxy(); Target target new Target(); proxy.setMethodInterceptor(new MethodInterceptor() { Override public Object intercept(Object p, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println(before...); return methodProxy.invoke(target, args); // 内部无反射, 结合目标用 return methodProxy.invokeSuper(p, args); // 内部无反射, 结合代理用 } }); proxy.save(); proxy.save(1); proxy.save(2L); }模拟cglib避免反射调用1.目标调用public class TargetFastClass { static Signature s0 new Signature(save, ()V); static Signature s1 new Signature(save, (I)V); static Signature s2 new Signature(save, (J)V); // 获取目标方法的编号 /* Target save() 0 save(int) 1 save(long) 2 signature 包括方法名字、参数返回值 */ public int getIndex(Signature signature) { if (s0.equals(signature)) { return 0; } else if (s1.equals(signature)) { return 1; } else if (s2.equals(signature)) { return 2; } return -1; } // 根据方法编号, 正常调用目标对象方法 public Object invoke(int index, Object target, Object[] args) { if (index 0) { ((Target) target).save(); return null; } else if (index 1) { ((Target) target).save((int) args[0]); return null; } else if (index 2) { ((Target) target).save((long) args[0]); return null; } else { throw new RuntimeException(无此方法); } } public static void main(String[] args) { TargetFastClass fastClass new TargetFastClass(); int index fastClass.getIndex(new Signature(save, (I)V)); System.out.println(index); fastClass.invoke(index, new Target(), new Object[]{100}); } }2.根据代理调用public class ProxyFastClass { static Signature s0 new Signature(saveSuper, ()V); static Signature s1 new Signature(saveSuper, (I)V); static Signature s2 new Signature(saveSuper, (J)V); // 获取代理方法的编号 /* Proxy saveSuper() 0 saveSuper(int) 1 saveSuper(long) 2 signature 包括方法名字、参数返回值 */ public int getIndex(Signature signature) { if (s0.equals(signature)) { return 0; } else if (s1.equals(signature)) { return 1; } else if (s2.equals(signature)) { return 2; } return -1; } // 根据方法编号, 正常调用目标对象方法 public Object invoke(int index, Object proxy, Object[] args) { if (index 0) { ((Proxy) proxy).saveSuper(); return null; } else if (index 1) { ((Proxy) proxy).saveSuper((int) args[0]); return null; } else if (index 2) { ((Proxy) proxy).saveSuper((long) args[0]); return null; } else { throw new RuntimeException(无此方法); } } public static void main(String[] args) { ProxyFastClass fastClass new ProxyFastClass(); int index fastClass.getIndex(new Signature(saveSuper, ()V)); System.out.println(index); fastClass.invoke(index, new Proxy(), new Object[0]); } }

相关新闻