java中的动态代理深入理解例子

        先看下代理类是怎么产生的,传目标类的加载器是为了使用该加载器加载代理类(个人理解),传目标类的实现接口时为了让代理类知道目标类有哪些方法,然后去实现这些方法,这也是为什么jdk动态代理要求目标类要实现接口(再深入的理解就是想要代理类去执行目标类的某个方法,那么这个方法必须在器实现的接口中。),后面的invocationHandler 匿名类 是为了当 代理类调用刚才实现的方法时,调用该匿名类的invoke方法,注意这个方法不能理解为是java反射中的那个invoke方法

Object proxy3 = Proxy.newProxyInstance(
				/*Collection.class.getClassLoader(),*/
				/*new Class[] { Collection.class},*/
				target.getClass().getClassLoader(),//调用目标类的加载器加载代理类
				target.getClass().getInterfaces(),//获得目标类的实现的方法(同时也是代理类实现的方法),当代理类调用这些方法时,会调用代理类的invoke方法。
				new InvocationHandler() {

        系统给代理类的通告,就是告诉代理类除了执行目标类原始方法之外,额外执行的方法。

package casic.com.base.proxytest;

import java.lang.reflect.Method;

/**
 * 
 * 通告 建议
 * Copyright © 2018 eSunny Info. Tech Ltd. All rights reserved.
 * @Package: casic.com.base.proxytest 
 * @author: lh   
 * @date: 2018年5月2日 下午10:08:52
 */
public interface Advice {
	 void beforeMethod(Method method);
	 void afterMethod(Method method);
}
package casic.com.base.proxytest;

import java.lang.reflect.Method;

public class MyAdvice implements Advice{
	long beginTime;
	@Override
	public void beforeMethod(Method method) {
		System.out.println("目标方法执行之前执行。。。");
		beginTime = System.currentTimeMillis();
		
	}

	@Override
	public void afterMethod(Method method) {
		System.out.println("目标方法执行结束之后执行。。。");
		long endTime = System.currentTimeMillis();
		System.out.println(method.getName() +"运行时间为" + (endTime - beginTime));
	}

}

最后整体上就是这个样子

package casic.com.base.proxytest;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
/**
 * Copyright © 2018 eSunny Info. Tech Ltd. All rights reserved.
 * 
 * @Package: casic.com.base.proxytest 
 * @author: lh   
 * @date: 2018年5月2日 下午8:57:41
 */
public class ProxyTest {

	public static void main(String[] args) throws Exception{

		final ArrayList target = new ArrayList();
		
		Collection proxy3 = (Collection) getProxy(target,new MyAdvice());
		proxy3.add("11");
		proxy3.add("22");
		proxy3.add("33");
		System.out.println(proxy3.size());
	}

	private static Object getProxy(final Object target,final Advice advice) {
		Object proxy3 = Proxy.newProxyInstance(
				/*Collection.class.getClassLoader(),*/
				/*new Class[] { Collection.class},*/
				target.getClass().getClassLoader(),//调用目标类的加载器加载代理类
				target.getClass().getInterfaces(),//获得目标类的实现的方法(同时也是代理类实现的方法),当代理类调用这些方法时,会调用代理类的invoke方法。
				new InvocationHandler() {
				
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						
					/*	long beginTime = System.currentTimeMillis();
						Object retVal = method.invoke(target, args);
						long endTime = System.currentTimeMillis();
						System.out.println(method.getName() +"运行时间为" + (endTime - beginTime));
						//return method.invoke(proxy, args); //死循环
						return retVal;*/
						
						advice.beforeMethod(method);
						Object retVal = method.invoke(target, args);
						System.out.println("调用目标方法"+method.getName());
						advice.afterMethod(method);
						return retVal;
					}
				});
		return proxy3;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值