动态代理V.S静态代理Proxy类代码是固定的,以后会因为业务越来越大,无法实现AOP编程。这是静态代理无法实现的解耦。如果在web业务下使用,动态代理可以实现数据层和业务层分离的好处是实现非侵入式代码扩展。静态代理模型本身就有很大的问题。如果类方法的数量增加,代理类的代码量会非常大。所以引入动态代理的关键Java实现动态代理的关键:ProxyInvocationHandlerInvocationHandler#invokemethod调用的方法,也就是要执行的方法args方法的参数proxy代理类实例图片JDK动态proxyJDK动态代理模式中有拦截在JDK中,只要实现了InvocationHandler接口的类就是拦截类。拦截器的作用:控制目标对象的目标方法的执行。拦截器的具体运行步骤:1.引入类目标类和一些与扩展方法相关的类2.赋值构造函数给相关对象赋值3.合并逻辑处理在invoke方法中将所有逻辑组合在一起.最后决定是否调用目标方法。以下面的问题为例:谁为代理对象生成JVM。与静态代理不同,我们必须自己创建一个新的代理对象。代理对象实现了什么接口?实现的接口就是目标对象实现的接口。静态代理中代理对象实现的接口。继承图还是一样。代理对象和目标对象都实现了一个公共接口。这是界面。所以Proxy.newProxyInstance()方法返回的类型就是这个接口类型。代理对象的方法体是什么?代理对象的方法体中的内容就是拦截器中invoke方法中的内容。所有代理对象的处理逻辑控制着是否执行目标对象的目标方法。都在这个方法中处理。拦截器中invoke方法中的方法参数是什么时候赋值的?在客户端,当代理对象调用目标方法时,在这个实例中是:proxyObj.business();真正进入的是拦截器中的invoke方法,那么拦截器中的invoke方法中的方法参数就会被赋值。这个为什么叫JDK动态代理,因为动态代理对象是用JDK相关代码生成的。很多同学一直对动态代理一头雾水,因为误解了proxyObj.business();$Proxy0没找到这个proxyObj和Proxy类的联系,一直很好奇最后调用的business()是怎么和invoke()联系起来的?invoke是怎么知道business的存在的?因为大部分同学不知道$Proxy0这个类,看看下面的$Proxy0源码,相信你就能完全理解动态代理了。虽然我们没有显式地调用invoke,但是这个方法被执行了。newProxyInstance方法可以作为突破口。我们看一下Proxy类中newProxyInstance方法的源码:finalSecurityManagersm=System.getSecurityManager();if(sm!=null){checkProxyAccess(Reflection.getCallerClass(),loader,intfs);}/**查找或生成指定代理类*创建代理类$Proxy0*$Proxy0类实现了接口的接口,继承了Proxy类*/Class>cl=getProxyClass0(loader,intfs);/**用指定的callhandler调用其构造函数*/try{if(sm!=null){checkNewProxyPermission(Reflection.getCallerClass(),cl);}//形参为InvocationHandler类型的构造函数finalConstructor>cons=cl.getConstructor(constructorParams);finalInvocationHandlerih=h;if(!Modifier.isPublic(cl.getModifiers())){AccessController.doPrivileged(newPrivilegedAction
