java代理模式

1.0关于代理 

  •  我们通常所说的java代理模式总共分为三种,分为:静态代理、jdk动态代理(接口代理)、cglib动态代理(子类代理)技术是整个java技术中最重要的一个技术,是java框架的基础,在Spring等框架中运用了大量的代理技术。
  • 在实际开发的过程中,我们经常调用别人写的代码完成业务需求开发,很多时候,我们想在原来实现的基础上稍微做一些调整扩展,但是又不能修改别人的代理,怎么办呢?代理可以解决。
  • 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式,即通过代理对象访问目标对象,这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。

1.1 代理模式 

  • 假如我们要去买电脑,我们通常需要去找电脑代理商购买,电脑代理商去电脑工厂提货,电脑代理商可以赚取中间的差价。 假如我们想买火车票,我们可以直接去12306网站买票。可是太难抢到票了,于是我们去找火车票的黄牛,让黄牛帮我们去12306买票,黄牛买到票再加价卖给我们,赚取中间的差价。

  • 你买电脑         ->              电脑代理商          ->                 电脑工厂
    你买火车票     ->              黄牛                                ->              12306
    调用者                               代理对象                                          真正干活的目标对象

  • 我们发现代理对象和真正干活的目标都具有相同的功能(卖电脑/卖票),代理可以在中间赚取差价(增强功能)。

1.2 代理模式的作用

  •  代理对象可以在调用者和目标对象之间起到中介的作用。代理对象可以对目标对象的功能进行增强。
  • 代理模式的作用:增强某一对象的某一个功能。

 1.3代理模式涉及到四个要素

  1. 调用者:你。
  2. 代理对象:联想电脑代理商/黄牛
  3. 目标对象(被代理对象):电脑工厂/12306
  4. 抽象对象:代理对象和目标对象都共有的接口,保证代理对象和真实对象都有相应的方法,如电脑代理商和电脑工厂都需要有卖电脑的功能。

java代理模式

2.1 什么是动态代理

  •  在程序运行的过程中,动态创建出代理对象

 2.2 动态代理相应的API

  • Proxy类:static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
  • 作用:生成实现指定接口的代理对象。
  • 参数说明:
  • loader参数:目标对象的类加载器
  • interfaces:代理对象实现的接口数组
  • h: 具体的代理操作,InvocationHandler是一个接口,需要传入一个实现了此接口的实现类。
  • 返回值:实现指定接口的代理对象。
  1. InvocationHandler接口
  • Object invoke(Object proxy, Method method, Object[] args)
  • 作用:在这个方法中实现对真实方法的增强。
  • 参数说明:
  1. proxy:即方法newProxyInstance()方法返回的代理对象,该对象一般不要在invoke方法中使用。
  2. method: 代理对象调用的方法对象。
  3. args:代理对象调用方法时传递的参数。
  4. 返回值:是真实对象方法的返回值。

 2.3 需求

模拟电脑代理商与电脑厂商之间的代理关系,最终实现代理商中间赚取差价。

  • 设计模式:解决这一类问题的固定步骤:
  • 固定步骤:
  1. 处理器内部一定要维护一个被代理对象。
  2. 一定需要在invoke方法内部获取方法名
  3. 如果不需要被代理的方法,直接让该方法执行即可,并且使用被代理对象去执行。
  4. 如果需要被代理的方法,那么就写上自己的业务逻辑即可。

java代理模式

1.公共接口

package com.sunny.proxy;

/**
 * 卖电脑、修电脑接口
 */
public interface Provide {
    public void sellComputer(double money);
    public void repairComputer(double money);
}

 2.电脑厂商类

package com.sunny.proxy;

public class ComputerFactory implements Provide {
    @Override
    public void sellComputer(double money) {
        System.out.println("电脑厂商收到了"+money+"钱,电脑发货...");
    }

    @Override
    public void repairComputer(double money) {
        System.out.println("电脑厂商收到了"+money+"钱,维修电脑...");
    }
}

3.电脑厂商代理类

package com.sunny.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ComputerProxy {
    /**
     * 电脑代理商
     * 动态代理的作用:增强一个对象的某个方法。
     * 动态代理涉及的类与方法:
     * Obejct proxy = Proxy.newProxyInstanceI(,A.class,B.clsss);   动态创建一个对象并且实现你指定的接口。
     * newProxyInstance(ClassLoader loader, Class[] interfaces, reflect.InvocationHandler h)
     *      loader: 类加载器,
            interfaces  : 指定代理对象需要实现的接口数组。
            InvocationHandler : 处理器。

     invoke(Object proxy, Method method, Object[] args)
             proxy : 当前的代理对象
             method: 当前调用的方法
             args: 当前传入的参数.
     */
    public static void main(String[] args) {
        /**
         * 得到一个电脑厂商的代理对象。动态代理对象帮你动态生成一个对象,实现了你指定的接口的方法,
         * 但是实现的时候全部都是空实现,如果需要实现具体的方法,那么需要处理器的invoke方法去实现。
         */
      Provide proxy = (Provide) Proxy.newProxyInstance(ComputerProxy.class.getClassLoader(), new Class[]{Provide.class}, new MyHandler());
      //代理对象只能使用接口定义的方法
      proxy.sellComputer(10000);
    }
}


class MyHandler implements InvocationHandler{
    //处理器内部一定要维护一个被代理对象
    ComputerFactory factory = new ComputerFactory();
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //获取当前调用的方法名
        String methodName = method.getName();
        //需求:代理你卖电脑的功能
        if("sellComputer".equalsIgnoreCase(methodName)){
            //代理你的功能
            double totalPrice = (double) args[0];
            double price = totalPrice*0.7;
            System.out.println("代理商收入了:"+totalPrice+"给了电脑厂商:"+price);
        }else {
            //不需要代理
            method.invoke(factory,args);
        }
        return null;
    }
}

卖电脑功能,需要代理 

java代理模式

java代理模式

修电脑功能,不需要代理,走else,结果为:电脑厂商收到了10000.0钱,维修电脑... 

java代理模式 java代理模式