java动态代理

动态代理

代理可以为已经存在的多个具有相同接口的目标类的各个方法增加一些系统功能。例如,异常处理,日志,计算方法的运行时间,事务管理等。

JDK中为我们提供了动态代理。

		Class clazzProxy = Proxy.getProxyClass(Collection.class
				.getClassLoader(), Collection.class);// 获取动态代理的字节码实例
		Constructor constructor = clazzProxy
				.getConstructor(InvocationHandler.class);// 利用反射取得构造器
		Collection proxyInstance = (Collection) constructor
				.newInstance(new InvocationHandler() {// 进行实例化,需实现InvocationHandler接口
					public ArrayList target = new ArrayList();// 目标对象

					@Override
					public Object invoke(Object proxy, Method method,
							Object[] args) throws Throwable {
						// TODO Auto-generated method stub
						Object retValue = method.invoke(target, args);
						return retValue;
					}

				});
		proxyInstance.add("java01");
		proxyInstance.add("java02");
		System.out.println(proxyInstance.size());
		System.out.println(proxyInstance.getClass());

上例中实例化代理对象时要实现InvocationHandler接口。代理对象调用方法时,都会转到InvocationHandler的invoke方法,最后对目标对象进行方法调用。

注意:代理类继承自Object的方法除了toString(),hashCode(),equals()经过invoke方法外,其他方法都是由代理类自己实现。

我们可以在invoke方法中增加代码以实现额外功能。

	public static Object getProxyInstance(final Object target,final MyAdvice advice) {
		return 
		Proxy.newProxyInstance(Collection.class.getClassLoader(),new Class[] {Collection.class}, new InvocationHandler() {
				@Override
				public Object invoke(Object proxy, Method method, Object[] args)
						throws Throwable {
					// TODO Auto-generated method stub
					advice.beforeMethod();
					Object retValue = method.invoke(target,args);
					advice.afterMethod();
					return retValue;
				}
			});
	}

自定义类MyAdvice

public class MyAdvice {
	public long beginTime;
	public long endTime;
	public void beforeMethod(){
		beginTime = System.currentTimeMillis();
		System.out.println("方法前");
	}
	public void afterMethod(){
		System.out.println("方法后");
		endTime = System.currentTimeMillis();
		System.out.println("方法运行时间为" +(endTime-beginTime) );
	}

}

测试如上方法

	ArrayList array = new ArrayList();
	MyAdvice advice = new MyAdvice();
	Collection proxy3 = (Collection) getProxyInstance(array,advice);
	proxy3.add("java02");
	System.out.println(proxy3.size());

如此只要调用proxy3的任何方法都可以计算出调用方法的时间。

注意:动态代理只能针对拥有接口的类,如果没接口就没法实现。这时候如果要使用代理可以使用第三方cglib.

代理是AOP编程的核心技术,学好代理能更好地理解AOP编程。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值