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

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

使用 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();
	}
	@Override
	public Object intercept(Object proxy, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		System.out.println("前驱........");
		Object result = methodProxy.invoke(this.targetObject, args);
		return result;
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值