设计模式(四)---- 代理模式

 

代理模式(Proxy Pattern)

核心作用:通过代理控制对象的访问;可以详细访问某个类或对象的方法,在调用这个方法之前做前置处理,调用这个方法之后做后置处理;(AOP的微实现)

核心角色:

  (1)抽象角色:定义代理角色和真实角色的公共对外方法;

  (2)真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用;(关注真正的业务逻辑)

  (3)代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法并附加自己的操作;将统一的流程控制放到代理角色中处理。

应用场景:

  安全代理:屏蔽堆真实角色的直接访问;

  远程代理:通过代理类处理远程方法调用(RMI);

  延时加载:先加载轻量级的代理对象,真正需要时在加载真实对象。

         

分类:

  静态代理(静态定义代理类)

    动态代理(动态生成代理类)

    JDK自带的动态代理;

    java assist 字节码操作实现;

    CGLIB

    ASM(底层使用指令,可维护性较差)

一、静态代理模式

抽象角色:

public interface Star
{
    void confer();      //面谈
    void signContract();//签合同
    void bookTicket();  //订票
    void sing();        //唱歌
    void collectMoney();//收钱
}

真实角色:

public class RealStar implements Star
{
    @Override
    public void confer()
    {
        System.out.println("RealStar.confer()");
    }

    @Override
    public void signContract()
    {
        System.out.println("RealStar.signContract()");
    }

    @Override
    public void bookTicket()
    {
        System.out.println("RealStar.bookTicket()");
    }

    @Override
    public void sing()
    {
        System.out.println("RealStar.sing(周杰伦)");
    }

    @Override
    public void collectMoney()
    {
        System.out.println("RealStar.collectMoney()");
    }
}

代理角色:

public class ProxyStar implements Star
{
    private Star star;

    public ProxyStar(Star star)
    {
        this.star = star;
    }

    @Override
    public void confer()
    {
        System.out.println("ProxyStar.confer()");
    }

    @Override
    public void signContract()
    {
        System.out.println("ProxyStar.signContract()");
    }

    @Override
    public void bookTicket()
    {
        System.out.println("ProxyStar.bookTicket()");
    }

    @Override
    public void sing()
    {
        star.sing();
    }

    @Override
    public void collectMoney()
    {
        System.out.println("ProxyStar.collectMoney()");
    }
}

测试代码:

public class Test
{
    public static void main(String[] args)
    {
        RealStar realStar = new RealStar();
       Star star = new ProxyStar(realStar);

        star.confer();
        star.signContract();
        star.bookTicket();
        star.sing();    //
        star.collectMoney();
    }
}

 

二、动态代理(Dynamic Proxy)

动态代理相比于静态代理的优点:

抽象角色(接口)中声明的所有方法都被转移到调用处理器一个集中的方法中,这样我们可以使用更加灵活统一的处理众多的方法。

1、JDK自带的类

(1)动态代理需要的处理

  java.lang.reflect.InvocationHandler (处理器接口):可以通过 invoke 方法实现对真实对象的代理访问;每次通过Proxy生成的代理类对象时都有指定代理器对象。

  java.lang.reflect.Proxy : 生成代理类和对象。

(2)代码实现:抽象角色、真实角色同上

代理角色:

public class ProxyStar implements InvocationHandler
{
    private Star star;

    public ProxyStar(Star star)
    {
        this.star = star;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable
    {
        Object object = null;

        System.out.println("签合同");
        System.out.println("定机票");
        if("sing".equals(method.getName()))  //执行的方法名为sing时, 调用真实角色的sing方法
        {
            object = method.invoke(star, args);
        }
        System.out.println("最后的方法执行");
        return object;
    }
}

测试类代码:

public class Test
{
    public static void main(String[] args)
    {
        Star realStar = new RealStar();
        InvocationHandler invocationHandler = new ProxyStar(realStar);

        //生成代理对象
        Star proxy = (Star) Proxy.newProxyInstance(
                RealStar.class.getClassLoader(), //ClassLoader.getSystemClassLoader(),
                RealStar.class.getInterfaces(),  //new Class[]{Star.class},
                invocationHandler);

        //只要调用了代理对象的任何一个方法都会进入 InvocationHandler 实现类的 invoke() 方法
        proxy.sing();
    }
}

 

posted @ 2018-11-13 00:22  风止雨歇  阅读(245)  评论(0编辑  收藏  举报