设计模式之代理模式

来源:互联网 发布:门户源码 编辑:程序博客网 时间:2024/06/06 12:40
  1. 理解:顾名思义就是代替别人做事情,在Java中就是为其他对象提供一种代理,以控制对这个对象的访问,起到一个中介的作用,就向火车票代售点,房产中介,职介所等这一类的工作,为被代理的对象如火车站,房子的业主,用人单位提供自己本身的卖票,卖房/租房,招聘等工作
  2. 分类:
    1. 远程代理:C/S模式
    2. 虚拟代理:根据需要将消耗资源很大的对象进行延迟创建,在真正需要时进行创建
    3. 保护代理:控制一个对象的访问权限
    4. 智能引用代理:提供对象的一些其他代理
  3. 举例智能引用代理中的静态代理和动态代理
    1. 静态代理:代理类和目标对象的类在编译期间就被确定下来了,都实现了相同的接口或者继承了同一个类,实现静态代理采用聚合的代码开发方式,便于代理类的功能扩展。同时,每一个代理类只能为一个接口服务,这样一来程序开发过程中必定要产生更多的代理
      按照实现接口的方式实现静态代理
package com.fgy.delegate;public interface Ticket {        public abstract void sellTickets();}

目标对象

package com.fgy.delegate;public class TrainStation implements Ticket {    @Override    public void sellTickets() {       System.out.println("火车站卖的票!!!!");    }}

代理对象

package com.fgy.delegate;public class SalePoint implements Ticket {    TrainStation trainstation;    public SalePoint(TrainStation trainStation) {        this.trainstation = trainStation;    }    @Override    public void sellTickets() {       System.out.println("代售点操作卖票");       trainstation.sellTickets();       System.out.println("代售点卖完票了");    }}

运行结果
这里写图片描述

②动态代理:就是在代理类和被代理类中间加了一个InvocationHandler,不指定代理类,让程序动态的创建代理。
③创建一个动态代理要解决的问题
1)如何根据加载到内存中的被代理对象,动态的去创建代理对象
2)如何通过代理类的对象调用接口中的方法时,实现对被代理对象的同名方法的调用
举例:
first:创建一个被代理类实现的接口

public interface Human {    void fly();    void say();}
sec:创建一个被代理类对象
package com.fgy.delegate;public class SuperMan implements Human {    @Override    public void fly() {        System.out.println("我是超人,我怕谁!!!!God!!!");    }    @Override    public void say() {        System.out.println("I believe I can fly!!!");    }}

Third:创建一个实现InvocationHandler接口的类

package com.fgy.delegate;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class MyInvocationHandler implements InvocationHandler {    private Object obj;//被代理对象    //将被代理对象绑定到    public void bind(Object obj) {        this.obj = obj;    }    //通过代理对象调用接口方法时,就会调用如下的handler    /**     * proxy:被代理对象     * method:被代理对象的方法     * args:方法的参数     *      * Object:方法的返回值     *      */    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        Object result = method.invoke(obj);        return result;    }}

用来专门生产代理的类

package com.fgy.delegate;import java.lang.reflect.Proxy;public class ProxyFactory {    //返回代理对象    public static Object getProxyInstance(Object obj) {//形参是被代理对象        MyInvocationHandler myInvocationHandler = new MyInvocationHandler();        myInvocationHandler.bind(obj);        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), myInvocationHandler);    }}

测试类:

package com.fgy.delegate;public class TestDelegate {    public static void main(String[] args) {        //创建被代理对象        SuperMan superMan = new SuperMan();        Object proxy = ProxyFactory.getProxyInstance(superMan);        Human human = (Human) proxy;        human.fly();        human.say();    }}

测试结果
这里写图片描述
以上就是动态代理的例子
Cglib动态代理和JDK动态代理的区别:
1. JDK 动态代理只能代理实现了接口的类,没有实现接口的类不能实现动态代理
2. Cglib是针对类来实现代理的,对指定目标类产生一个子类,通过方法拦截技术拦截所有父类方法的调用