代理模式
目录
代理模式的定义
代理模式(proxy pattern)是指为其他对象提供一种代理,以控制对这个对象的访问,代理对象在客户端和目标对象之间起到中介作用,属于结构型设计模式。
java原生实现动态代理
实现原理:
1、动态生成源码.java
2、java文件输出到磁盘,保存为$proxy0(累加).java
3、把.java文件编译成$proxy0.class
4、把生成的.class文件加载到JVM中
5、返回新的代理对象
注意事项:
动态代理类需实现invocationHandler接口
调用方式:
Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
实现invoke方法
before();----前置
method.invoke(this.proxy,args);
after();----后置
剖析流程:
如需查看源码可以在java反射包下面proxy
java会在内存中生成一个代理类可用
ProxyGenerator.generateProxyClass("类名",new Class[] {接口.class});
然后用输出流存在硬盘上,反编译之后查看源码
Tip:super.h = 动态代理类
Cglib动态代理
注意事项:
动态代理类需实现MethodInterceptor接口
调用方式:
//proxy代理的工具类
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
实现intercept方法
before();----前置
methodProxy.invokeSuper(o,objects);
after();----后置
添加类库:
<dependency>
<groupId>cglib</groupId>
<artifactId>bglib-nodep</artifactId>
<version>2.2</version>
</dependency>
Cglib动态代理与java原生实现动态代理的优缺点
对比JDK优点
1、不需要前置条件 继承一个接口 因为他底层是直接继承了需要代理的目标类
2、通过fastclass 优化了性能,底层没有用到反射
对比JDK缺点
1、因为是继承,所以目标不能有final的方法,会忽略此方法
Tip:如果目标类没有声明接口,则Spring将自动使用Cglib动态代理,反之则会使用JDK动态代理。加上<aop:aspectj-autoproxy proxy-target-class="true"/>则会自动使用Cglib。