Java|静态代理动态代理

#Java [字体 ··]

一个简单的"代理"模型图

代理的功能也就如这个模型一样, 对销售这个流程多了些处理, 原先供应商直接出售给客户的商品, 由代理商宣传销售.

代理在 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 运行时生成,然后通过覆盖父类的方法实现代理。


博客没有评论系统,可以通过 邮件 评论和交流。 Top↑