先定义一个接口SaleComputer
package cn.itcast.proxy;
public interface SaleComputer {
public String sale(double money);
public void show();
}
然后定义一个类实现这个接口
package cn.itcast.proxy;
/**
* 真实类
*/
public class Lenovo implements SaleComputer {
@Override
public String sale(double money) {
System.out.println("花了"+money+"元买了一台联想电脑...");
return "联想电脑";
}
@Override
public void show() {
System.out.println("展示电脑....");
}
}
下面就是动态代理,创建一个代理对象去增强真实对象的方法,增强的方式包括:1.增强方法的参数,2.增强方法的返回值,3.增强方法的方法体,这里我只谈谈自己对增强返回值的看法和理解吧。
首先,创建代理对象的套路都是死的,代码如下:
SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//使用真实对象调用该方法
String obj = (String) method.invoke(lenovo, args);
return obj;
}
});
代理对象创建好了,以后就通过调用proxy_lenovo来取代真实对象lenovo,例如,
String computer = proxy_lenovo.sale(8000);
我们来分析下动态代理的实现原理或者说程序执行的步骤吧。
首先,当代理对象创建完后,我们通过proxy_lenovo.sale(8000);来实现业务逻辑时,当程序执行这条语句后,会自动跳转进invoke方法体中,同时会将方法名(sale)封装为Method对象,参数(8000)封装进args集合,然后作为参数传进invoke方法,当程序执行到method.invoke(lenovo, money);实际上还是通过真实对象lenovo调用sale方法,实际上这是通过反射实现的,由此也可看出反射的强大之处,而invoke方法最后return的值实际上最终会返回给proxy_lenovo.sale(8000);这条语句。由此动态代理也就实现了。
下面重点说说怎样实现对方法返回值的增强,我们注意到,在invoke中,我们通过method.invoke(lenovo, args);调用了lenovo的方法sale,方法的返回值就是obj,如何我们对obj进行一些业务逻辑操作,使之改变为另一个值,再将其返回,不是就实现了返回值的增强(改变)了吗?