一个简单的"代理"模型图
代理的功能也就如这个模型一样, 对销售这个流程多了些处理, 原先供应商直接出售给客户的商品, 由代理商宣传销售.
代理在 java 中, 一般是对方法做出一些修改, 具体要看应用场景, 如:
- 抽离多个方法中重复代码(Spring AOP 就是这样)
- 过滤器, 拦截器
- 对其他包中对象的方法进行修改/增强
静态代理
==需要代理类实现被代理类的接口.==
被代理类和接口
1public interface ISell {
2 void sell(double money);
3}
4
5class Seller implements ISell {
6 public void sell(double money) {
7 System.out.println("厂商得到:" + money);
8 }
9}
静态代理类实现
1class StaticProxySeller implements ISell {
2 private Seller superSeller;
3
4 public StaticProxySeller(Seller seller) {
5 this.superSeller = seller;
6 }
7
8 public void sell(double money) {
9 //获取利润 todo
10 double profit = money * 0.2;
11 System.out.println("代理销售利润:" + profit);
12 //调用被代理类的对应方法
13 superSeller.sell(money - profit);
14 //todo
15 }
16}
Proxy 动态代理
使用 Proxy 工具类中的 newInstance()方法实现. 在程序执行过程中对某个对象进行代理, 实现方法的增强. newInstance 的三个参数:
- 被代理类的加载器
- 被代理类的接口
- 处理增强的方法(handler)
内部内简洁实现
1ISell ProxySeller = (ISell) Proxy.newProxyInstance(seller.getClass().getClassLoader(), seller.getClass().getInterfaces(), new InvocationHandler() {
2 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
3 if (method.getName().equals("sell")) {
4 //获取利润 todo
5 Double money = (Double) args[0];
6 double profit = money * 0.2;
7 System.out.println("代理销售利润:" + profit);
8 method.invoke(superSeller, money - profit);
9 //todo
10 }
11 return superSeller;
12 }
13 });
外部 handler 实现
1class Handler implements InvocationHandler {
2 private Seller superSeller;
3
4 public Handler(Seller seller){
5 this.superSeller = seller;
6 }
7
8 /**
9 * 对代理方法增强的类
10 *
11 * @param proxy 在其上调用方法的代理实例, 相当于Proxy的this(功能相同), 但是不是
12 * @param method 被代理类的方法对象
13 * @param args 被代理对象的方法的参数
14 * @return
15 * @throws Throwable
16 */
17 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
18 if ("sell".equals(method.getName())) {
19 //获取利润 todo
20 Double money = (Double) args[0];
21 double profit = money * 0.2;
22 System.out.println("代理销售利润:" + profit);
23 method.invoke(superSeller, money - profit);
24 //todo
25 }
26 return superSeller
27 }
28}
代理类对象
1Handler hander = new Handler();
2ISell ProxySeller = (ISell) Proxy.newProxyInstance(seller.getClass().getClassLoader(),seller.getClass().getInterfaces(),handler);
动态代理方法执行流程
cglib 动态代理
cglib 动态代理通过继承的方式实现,继承的子类再 jvm 运行时生成,然后通过覆盖父类的方法实现代理。