动态代理是设计模式中代理(委托)模式的变形。代理模式的实现需要一个与被代理类拥有相同接口的代理类,然后所有对被代理类调用的方法都改为向代理类调用。代理类可以修改被代理类返回的结果也可以不做处理,或者使用自己的处理。这在当修改现有的模块功能而不能修改现有类实现的情况下(即该类已经被其他模块调用,一旦修改会带来大量的副作用)很有用处。
动态代理是在运行时可对某实现某接口的类进行代理模式的操作。以下是动态代理的简单代码,也是动态代理的框架式代码。
// 业务接口
interface Itaobao{
int userpay(int money, int cast);
String userbuy(String name);
}
// 现有的业务处理类
class taobao implements Itaobao{
@Override
public int userpay(int money, int cast) {
return money - cast;
}
String name;
public void setName(String na){name = na;}
public int method(int a, int b){return a*2+b;}
@Override
public String userbuy(String name) {
return this.name + " buying " + name + " ";
}
}
public class DynamicProxy {
private static Itaobao getproxytaobao(){
Object proxytaobao = Proxy.newProxyInstance(taobao.class.getClassLoader(), new Class[]{Itaobao.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//System.out.println("invoke:" + proxy.toString()); //栈溢出错误
System.out.println("method:" + method.toString());
//System.out.println("args:" + proxy.toString()); //栈溢出错误
Object returnValue = method.invoke(new taobao(), args); //调用被代理的业务类返回结果
// SOME PROCESS is HERE
return returnValue;
}
});
return (Itaobao)proxytaobao; //返回使用 Proxy.newProxyInstance 构建的类对象
}
public static void main(String[] args) throws Exception {
//使用class类对象使用反射创建类对象的例子。
taobao.class.newInstance().userpay(5, 4);
//System.out.println(Arrays.asList(taobao.class.getDeclaredMethod( "method")));//不能是接口方法
Method m = taobao.class.getDeclaredMethod("method",int.class,int.class); //使用方法名的参数类型约束JVM解释器找到正确的方法。
System.out.println(m.invoke(new taobao(), 998,889)); //invoke方法
Itaobao protaobao = getproxytaobao();
//((taobao)protaobao).setName("马上风"); //无法正确向下转型,动态代理类不能转型为被代理类型。因为他只有接口方法。
System.out.println(protaobao.userbuy("女装"));
}
}