某男子9527

导航

 
  1. 什么是代理?
  2. 静态代理与动态代理
  3. JDK代理实例
  4. CGlib代理实例
  5. 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实现动态代理

被代理目标不能直接对类类型对象进行代理,代理对象必须是接口且必须有实现类

 

posted on 2017-11-14 15:42  某男子9527  阅读(247)  评论(0)    收藏  举报