动态代理的实现1-简单实现

来源:互联网 发布:cad2013 软件闪退 编辑:程序博客网 时间:2024/05/16 01:43

1,

2,


3,


4,

5,


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(){@Overridepublic 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();@Overridepublic 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 */}}

使用CGLIB生成代理
CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。

import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class CGLIBProxyFactory implements MethodInterceptor {private Object targetObject;public Object createProxyInstance(Object targetObject){this.targetObject = targetObject;Enhancer enhancer = new Enhancer();enhancer.setSuperclass(targetObject.getClass());enhancer.setCallback(this);return enhancer.create();}@Overridepublic Object intercept(Object proxy, Method method, Object[] args,MethodProxy methodProxy) throws Throwable {System.out.println("前驱........");Object result = methodProxy.invoke(this.targetObject, args);return result;}}



原创粉丝点击