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