Java 静态代理动态代理

目录

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

代理在 java 中, 一般是对方法做出一些修改, 具体要看应用场景, 如:

  • 抽离多个方法中重复代码(Spring AOP 就是这样)
  • 过滤器, 拦截器
  • 对其他包中对象的方法进行修改/增强

静态代理

需要代理类实现被代理类的接口。

在这里插入图片描述

被代理类和接口

public interface ISell {
	void sell(double money);
}

class Seller implements ISell {
	public void sell(double money) {
		System.out.println("厂商得到:" + money);
	}
}

静态代理类实现

class StaticProxySeller implements ISell {
	private Seller superSeller;

	public StaticProxySeller(Seller seller) {
		this.superSeller = seller;
	}

	public void sell(double money) {
			//获取利润 todo
			double profit = money * 0.2;
			System.out.println("代理销售利润:" + profit);
			//调用被代理类的对应方法
			superSeller.sell(money - profit);
			//todo
	}
}

Proxy 动态代理

使用 Proxy 工具类中的 newInstance()方法实现. 在程序执行过程中对某个对象进行代理, 实现方法的增强. newInstance 的三个参数: 在这里插入图片描述

  • 被代理类的加载器
  • 被代理类的接口
  • 处理增强的方法(handler)

内部内简洁实现

ISell ProxySeller = (ISell) Proxy.newProxyInstance(seller.getClass().getClassLoader(), seller.getClass().getInterfaces(), new InvocationHandler() {
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				if (method.getName().equals("sell")) {
					//获取利润 todo
					Double money = (Double) args[0];
					double profit = money * 0.2;
					System.out.println("代理销售利润:" + profit);
					method.invoke(superSeller, money - profit);
					//todo
				}
				return superSeller;
			}
		});

外部 handler 实现

class Handler implements InvocationHandler {
	private Seller superSeller;

	public Handler(Seller seller){
		this.superSeller = seller;
	}

	/**
	 * 对代理方法增强的类
	 *
	 * @param proxy  在其上调用方法的代理实例, 相当于Proxy的this(功能相同), 但是不是
	 * @param method 被代理类的方法对象
	 * @param args   被代理对象的方法的参数
	 * @return
	 * @throws Throwable
	 */
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		if ("sell".equals(method.getName())) {
			//获取利润 todo
			Double money = (Double) args[0];
			double profit = money * 0.2;
			System.out.println("代理销售利润:" + profit);
			method.invoke(superSeller, money - profit);
			//todo
		}
		return superSeller
	}
}

代理类对象

Handler hander = new Handler();
ISell ProxySeller = (ISell) Proxy.newProxyInstance(seller.getClass().getClassLoader(),seller.getClass().getInterfaces(),handler);

动态代理方法执行流程 在这里插入图片描述

cglib 动态代理

cglib 动态代理通过继承的方式实现,继承的子类再 jvm 运行时生成,然后通过覆盖父类的方法实现代理。