代理(Proxy)模式

代理(Proxy)模式介绍

作用:通过代理可以控制访问某个对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理。(即: AOP的微观实现!)

代理(Proxy)模式_第1张图片

核心角色

  • 抽象角色(接口):定义公共对外方法

  • 真实角色(周杰伦):实现抽象角色,定义真实角色所要实现的业务逻辑

  • 代理角色(代理人):实现抽象角色,是真实角色的代理,通过调用真实角色的方法来完成业务逻辑,并可以附加自己的操作

代理(Proxy)模式_第2张图片

代理模式
        1)静态代理
            角色:
                公共接口:Star
                真实角色:RealStar(周杰伦.唱歌)
                代理角色:ProxyStar(代理人.面谈.订机票.签合同.[调周杰伦唱歌].收尾款)
                客户类:Client(小孩.调代理人)

            缺陷:1.大量代码重复 2.只能代理Star类型的对象
        2)jdk动态代理
            角色:
                公共接口:Star
                真实角色:RealStar(周杰伦.唱歌)
                代理工厂:ProxyFactroy{生成ProxyStar(宋吉吉.面谈.订机票.签合同.[调周杰伦唱歌].收尾款)}
                客户类:Client(小孩.调代理人)

        3)Cglib动态代理
            cglib和jdk动态代理的区别:cglib真实角色没有接口

静态代理

抽象角色(公共接口)
public interface Star {
	/**
	 * 面谈
	 */
	void confer();
	/**
	 * 签合同
	 */
	void signContract();
	/**
	 * 订票
	 */
	void bookTicket();
	/**
	 * 唱歌
	 */
	void sing();
	/**
	 * 收钱
	 */
	void collectMoney();
}
真正角色(周杰伦)
public class RealStar implements Star{


    public void confer() {

    }


    public void signContract() {

    }


    public void bookTicket() {

    }


    public void sing() {
        System.out.println("静态代理方法周杰伦:天青色等烟雨,而我在等你...");
    }


    public void collectMoney() {

    }
}
代理角色(经纪人)
public class ProxyStar implements Star{


    private Star Star;

    public ProxyStar(Star Star) {
        this.Star = Star;
    }
    public void bookTicket() {
        System.out.println("ProxyStar.bookTicket()");
    }

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

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

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

    public void sing() {
        Star.sing();
    }
}
测试(Client)
public class Client {
    public static void main(String[] args) {
        Star star = new ProxyStar(new RealStar());
        star.confer();
        star.signContract();
        star.bookTicket();
        star.sing();
        star.collectMoney();
    }
}
测试结果 

代理(Proxy)模式_第3张图片

静态代理的缺点
  1. 代理类和实现类实现了相同的接口,这样就出现了大量的代码重复。

  2. 代理对象只服务于一种类型的对象。如果要服务多类型的对象,例如代码是只为UserService类的访问提供了代理,但是还要为其他类如DeptService类提供代理的话,就需要我们再次添加代理DeptService的代理类。

jdk动态代理

抽象角色(公共接口)
public interface Star {
    /**
     * 唱歌
     */
    void sing();
}
真正角色(周杰伦)
//真实角色(周杰伦)
public class RealStar implements Star{
    @Override
    public void sing() {
        System.out.println("动态代理方法周杰伦:天青色等烟雨,而我在等你...");
    }
}
代理角色(经纪人)---->代理工厂
//代理类工厂
public class ProxyFactory {
    //优点:此时可以代理任意类型的对象
    //真实角色(周杰伦)
    private Object realObj;

    public ProxyFactory(Object realObj) {
        this.realObj = realObj;
    }
    //获得代理对象
    public Object getRealObj() {
        /**
         * Proxy:作用创建代理对象
         *      ClassLoader loader:类加载器
         *      Class[] interfaces:真实角色实现的接口,根据接口生成代理类
         *      InvocationHandler h:增强的逻辑,即如何代理(代理人要做的事)
         */
       return Proxy.newProxyInstance(
               realObj.getClass().getClassLoader(),
               realObj.getClass().getInterfaces(),
               new InvocationHandler() {
                   @Override
                   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                       System.out.println("真正的方法执行前!");
                       System.out.println("面谈,签合同,预付款,订机票");
                       Object result = method.invoke(realObj, args);
                       System.out.println("真正的方法执行后!");
                       System.out.println("收尾款");
                       return result;
                   }
               }
       );
    }
}
测试(Client)
public class Client {
    public static void main(String[] args) {
        //获得代理对象
        Star star = (Star) new ProxyFactory(new RealStar()).getRealObj();
        star.sing();
    }
}
测试结果 

代理(Proxy)模式_第4张图片

你可能感兴趣的:(代理模式)