public class Test {
public static void main(String[] args) throws Exception{
//第一种实现方式:分步骤操作
Class clazzproxy=Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
Constructor consproxy=clazzproxy.getConstructor(InvocationHandler.class);
Collection con1=(Collection) consproxy.newInstance(new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
});
System.out.println(con1);//打印结果是"null"
//不会报错,首先会先生成一个临时的代理类$Proxy0,然后这个代理类实现Collection
//然后这个代理类的内部会调用InvocationHandler的invo方法
con1.clear();
//会报空指针错误,原因是在调用InvocationHandler的invo方法时会返回null
//但是size()方法的返回值是int类型
// con1.size();
//第二种实现方式:整合在一个方法中进行操作,但是日志功能都是硬编码在代理中
Collection con = (Collection)Proxy.newProxyInstance(
Collection.class.getClassLoader(),
new Class[]{Collection.class},
new InvocationHandler() {
List target=new ArrayList();
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("开始记录日志....");
System.out.println(proxy.getClass().getName());
System.out.println("运行方法名:"+method.getName());
System.out.println("运行方法参数值:"+Arrays.toString(args));
//在这里可以对参数args进行过滤,也可以对返回的结果进行修改
Object obj = method.invoke(target, args);
System.out.println("记录日志结束....");
System.out.println();
return obj;
}
}
);
con.add("aa");
con.add("bb");
con.add("cc");
System.out.println(con.size());
System.out.println(con.getClass().getName());//$Proxy0
//这里为什么返回的是$Proxy0 而不是ArrayList呢,那是因为在使用动态代理的过程中
//会生成一个临时的代理类$Proxy0,详细可看设计模式中的动态代理
/** 运行结果:
开始记录日志....
$Proxy0
运行方法名:add
运行方法参数值:[aa]
记录日志结束....
开始记录日志....
$Proxy0
运行方法名:add
运行方法参数值:[bb]
记录日志结束....
开始记录日志....
$Proxy0
运行方法名:add
运行方法参数值:[cc]
记录日志结束....
开始记录日志....
$Proxy0
运行方法名:size
运行方法参数值:null
记录日志结束....
3
$Proxy0
*/
}
}