动态代理
静态代理:自己创建代理对象;
动态代理:自动创建代理对象;
生成代理类的字节码文件
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags)
spring中代理对象生成器
JdkDynamicAopProxy
动态代理和拦截器都是AOP 思想
拦截器只要是做校验业务;
动态代理属于代码增强;
代理类工厂:这个类会帮住我们生成一个具体代理类:
public class FactoryProxy implements InvocationHandler { private Object abcFactory; public FactoryProxy(Object abcFactory) { this.abcFactory = abcFactory; } public void setAbcFactory(Object abcFactory) { this.abcFactory = abcFactory; } public Object getInstance(){ return Proxy.newProxyInstance(abcFactory.getClass().getClassLoader(),abcFactory.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("欢迎来到大汗工厂");
//这里需要注意不要将proxy当做目标对象传入,代理类在调用的时候传入的是代理对象本身,比如我们想让代理对象帮我们执行getObject方法,
// public final void getObject(String var1, String var2) throws {
// try {
// super.h.invoke(this, m3, new Object[]{var1, var2});
// } catch (RuntimeException | Error var4) {
// throw var4;
// } catch (Throwable var5) {
// throw new UndeclaredThrowableException(var5);
// }
// }这个代理类内部的getObject方法
//调用到我们当前方法,当前方法通过反射又去调用上面这个方法,会死循环;
Object invoke = method.invoke(this.abcFactory, args); System.out.println("欢迎下次光临"); return invoke; } }
public final class proxyTest extends implements ABCFactory { private static Method m1; private static Method m3; private static Method m2; private static Method m0; public proxyTest(InvocationHandler var1) throws { super(var1); }; public final boolean equals(Object var1) throws { try { return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue(); } catch (RuntimeException | Error var3) { throw var3; } catch (Throwable var4) { throw new UndeclaredThrowableException(var4); } } public final void getObject(String var1, String var2) throws { try { super.h.invoke(this, m3, new Object[]{var1, var2}); } catch (RuntimeException | Error var4) { throw var4; } catch (Throwable var5) { throw new UndeclaredThrowableException(var5); } } public final String toString() throws { try { return (String)super.h.invoke(this, m2, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } public final int hashCode() throws { try { return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue(); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")}); m3 = Class.forName("servlet.ABCFactory").getMethod("getObject", new Class[]{Class.forName("java.lang.String"), Class.forName("java.lang.String")}); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); } catch (NoSuchMethodException var2) { throw new NoSuchMethodError(var2.getMessage()); } catch (ClassNotFoundException var3) { throw new NoClassDefFoundError(var3.getMessage()); } } }
以上是程序帮我们生成的代理类;
这个类实现了目标对象的接口和继承Proxy类;
内部重写目标对象接口中的方法;
代理类内部组合了我们定义的FactoryProxy 也就是InvocationHandler
调用这个InvocationHandler的invoca方法 把调用的方法和参数传过去;
真正执行的这个方法的是被代理的类;
代理类中用就静态变量保存接口中定义的方法;
spring中@Transactional就是动态代理实现的;
代理类是复用的;
由于查看spring中类似Transactional 的注解很多,那么是怎么进行aop 的呢?
我将生成的代理类进行了第二次代理;
public static void main(String[] args) { ABCFactory abcFactory = new ABCFactoryImpl(); FactoryProxy factoryProxy = new FactoryProxy(abcFactory); ABCFactory instance = (ABCFactory)factoryProxy.getInstance(); TowPtoxy towPtoxy = new TowPtoxy(instance); ABCFactory o = (ABCFactory)Proxy.newProxyInstance(instance.getClass().getClassLoader(), instance.getClass().getInterfaces(), towPtoxy); FileOutputStream fileOutputStream = null; o.getObject("123456","韩"); try { byte[] proxyClassFile = ProxyGenerator.generateProxyClass( "proxyTest", instance. getClass().getInterfaces()); File file = new File("D://proxy.class"); fileOutputStream = new FileOutputStream(file); fileOutputStream.write(proxyClassFile); }catch (Exception e){ System.out.println("出现异常"); }finally { try { if(fileOutputStream!=null){ fileOutputStream.flush(); fileOutputStream.close(); } }catch (Exception e){ } } }
public class TowPtoxy implements InvocationHandler { private Object object; public TowPtoxy(Object object) { this.object=object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("第二次加强"); Object invoke = method.invoke(object, args); System.out.println("第二次加强结束"); return invoke; } }
代理后输出如下
第二次加强
欢迎来到大汗工厂
生产商品:123456:韩
欢迎下次光临
第二次加强结束
成功了
代理类没有变化;
spring的实现 :
代理类:JdkDynamicAopProxy(类似我们的FactoryProxy)
MethodInvocation方法调用;关键方法proceed()
proceed方法中 遍历拦截器
所有拦截器接口
调用MethodInterceptor的
invoke()
方法同时将MethodInvocation传入进去 类似于上下文信息;
invoke()中执行增强前置方法比如开启事务 之后调用
MethodInvocation的proceedWithInvocation()
最后在finally中执行后置增强;比如提交回滚

浙公网安备 33010602011771号