- 什么是代理?
- 静态代理与动态代理
- JDK代理实例
- CGlib代理实例
- CGLib 与JDK动态代理的区别
1、代理模式是Java中常见的一种模式,英文名字叫走Proxy或者Surrogate,代理的本意是一个人代表另一个人,或者一个机构代表另一个机构,采取行动,因而,代理和现实生活中的中介有很大的类似,你买房子、卖房子,可以自己去操作,但是需要了解和买卖房产无关的细节,如契税等,而找一个中介,则不用关心这些与买卖房产无直接关系的中间细节,只关心业务本身、如代理商等。
模式中包含的角色及其职责
Subject:抽象主题角色,抽象主题类可以是抽象类,也可以是接口,是一个最普通的业务类型定义,无特殊要求。
RealSubject:具体主题角色,也叫被委托角色、被代理角色。是业务逻辑的具体执行者。
Proxy:代理主题角色,也叫委托类、代理类。它把所有抽象主题类定义的方法给具体主题角色实现,并且在具体主题角色处理完毕前后做预处理和善后工作。(最简单的比如打印日志、事务管理)
2、静态代理与动态代理
代理分为静态代理和动态代理
按照代理创建的时期,可以分为动态代理和静态代理:
静态代理:由程序员或者自动生成工具生成代理类,然后进行代理类的编译和运行。在代理类、委托类运行之前,代理类已经以.class的格式存在。
静态代理:在程序运行时,由反射机制动态创建而成。一般不会这种方式。
动态代理:在程序运行过程中动态生成代理类,为目标对象提现代理服务。动态代理又可以分为jdk动态代理和cglib动态代理。
3、jdk动态代理实例
3.1目标对象
1 /** 2 * 设计模式-代理模式
代理对象 3 */ 4 public interface IProxy { 5 void say(); 6 void play(); 7 }
3.2实现类
/* IProxy 实现 */ public class IProxyImpl implements IProxy { @Override public void say() { System.out.println("say method"); } @Override public void play() { System.out.println("play method"); } }
3.3 JDK实现代理类
// jdk动态代理实现 public class ProxyHanler implements InvocationHandler { // 指定要代理的目标 IProxy proxyTarget; ProxyHanler(IProxy iProxy) { this.proxyTarget = iProxy; } ProxyHanler() {} public void start() { System.out.println("代理类调用invoke之前---"); } public void end() { System.out.println("代理类调用invoke之后---"); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { ProxyHanler ph = new ProxyHanler(); ph.start(); Object target = method.invoke(proxyTarget, args); ph.end(); return target; } }
3.4JDK代理测试类
public class Test_JDK_Proxy { public static void main(String[] args) { IProxyImpl iproxy = new IProxyImpl();//被代理目标的实现类 ProxyHanler hanler = new ProxyHanler(iproxy);//代理类 IProxy moveProxy = (IProxy) Proxy.newProxyInstance(//代理类与目标类交由代理实例处理 iproxy.getClass().getClassLoader(), iproxy.getClass().getInterfaces(), hanler); System.out.println("动态代理对象的类型:"+ moveProxy.getClass().getName()); moveProxy.say(); System.out.println("*****************************"); moveProxy.play(); } }
4、cglib动态代理
4.1.代理目标参考3.2
4.2 .cglib实现代理类
public class IProxy_Cglib_proxy implements MethodInterceptor { private IProxyImpl target; public IProxyImpl getInstance(IProxyImpl target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); // 回调方法 enhancer.setCallback(this); // 创建代理对象 return (IProxyImpl)enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("事物开始"); methodProxy.invokeSuper(o, objects); System.out.println("事物结束"); return null; } }
4.3、测试
public class Test_CGLib_proxy { public static void main(String[] args) { IProxy_Cglib_proxy icp = new IProxy_Cglib_proxy(); IProxyImpl iProxy = icp.getInstance(new IProxyImpl()); iProxy.say(); iProxy.play(); } }
5,CGLib 与JDK动态代理的区别
cglib 实现动态代理
该方式针对类 类型的目录对象使用,
cglib是针对类来实现代理的,
他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,
但因为采用的是继承,所以不能对final修饰的类进行代理
jdk实现动态代理
被代理目标不能直接对类类型对象进行代理,代理对象必须是接口且必须有实现类
浙公网安备 33010602011771号