JDK动态代理
说到代理模式或者aop的代理,大家都会想到jdk的动态代理和cglib的动态代理,其实代理模式使用的十分广泛,不仅仅是spring aop,在其他的优秀的框架也都使用了代理模式,所以说学好并且深入理解动态代理对我们学习使用框架有着十分大的帮助,这可以使我们更加深入理解各种框架。
接下来就举个例子,来帮助大家来认识一下动态代理。
首先我们需要有个被代理对象(也就是我们需要增强的目标类),一个接口(jdk的代理是基于接口的代理),一个测试类。如下图我们先进行通俗分析一下。如果我们购买电脑,直接从原产家买那肯定是没有中间商赚差价,现在了,我们就是要做那个中间商(这里可以实现我们的业务增强)。
jdk的动态代理基于接口的代理,增强代理类和被代理类更像兄弟,他们都是直接或间接实现了一个接口。如图
接下来上代码
//b被代理对象
public class Lenovo implements Sell{
@Override
public String sell(Double money) {
return "花了"+money+"买了电脑";
}
@Override
public void show() {
System.out.println("这是一台联想电脑");
}
}
//出售电脑接口
public interface Sell {
/**
* @param money 花的钱
* @return 打印一句话
*/
String sell(Double money);
//简单的展示
void show();
}
public class Test {
public static void main(String[] args) {
//lenovo是需要被代理的对象
Lenovo lenovo = new Lenovo();
/**
* jdk的动态代理是基于接口的动态代理,lenovo是需要被代理的对象,
* lenovo_proxy就是lenovo被代理增强完后的对象
* 类.getClass().getClassLoader() 需要被代理的对象类加载器
* 类.getClass().getInterfaces() 需要被代理的对象的实现的接口
* new InvocationHandler() 是我们集中处理增强的业务编写区
*/
Sell lenovo_proxy = (Sell) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(),
lenovo.getClass().getInterfaces(), new InvocationHandler() {
@Override
/**
* Object proxy 被代理对象
* Method method 被代理的方法(需要增强的方法)
* Object[] args 参数
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/**三种增强方法是
* 1 对参数增强
* 2 对返回结果增强
* 3 对整个方法体增强
*/
Object invoke = null;
if (method.getName().equals("sell")){
Double money = (Double) args[0];
//1 对参数增强 截取到参数 ,对参数进行篡改
money = 0.85*money;
System.out.println("专车接。。。。");
//2 对返回结果增强 拿到返回值对返回值进行篡改
invoke = method.invoke(lenovo, money).toString()+"_再送一只鼠标";
System.out.println("送货上门。。。。");
}else {
invoke = method.invoke(lenovo, args);
}
return invoke;
}
});
String sell = lenovo_proxy.sell(8000.0);
System.out.println(sell);
}
}
1200买一个鼠标垫真香