`
在水伊方
  • 浏览: 107187 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

黑马程序员-java高新技术08

阅读更多

----------------------android培训java培训、java学习型技术博客、期待与您交流!----------------------

 

动态代理技术:

要为系统中的各种接口的类增加代理功能,那将需要太多的代理类,全部采用静态代理方式,将是一件非常麻烦的事情!

JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。

JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。

CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。

代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法中的如下四个位置加上系统功能代码:

1.在调用目标方法之前

2.在调用目标方法之后

3.在调用目标方法前后

4.在处理目标方法异常的catch块中

 

下面的代码演示如何产生一个动态类:

public class ProxyTest {
	public static void main(String[] args) throws Exception {
		//创建动态类Proxy.getProxyClass(Classloader, class);
		Class clazzProxy = Proxy.getProxyClass(Collection.class
				.getClassLoader(), Collection.class);		 
	
		//获得动态类的构造函数
		Constructor constructor = clazzProxy.getConstructor(InvocationHandler.class);
		
		//编写一个InvocationHandler的实现类
		class MyInvocationHander1 implements InvocationHandler {

			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				return null;
			}
			
		}
		
		//实例化一个Collection对象
		Collection proxy1 = (Collection) constructor.newInstance(new MyInvocationHander1());
		System.out.println("proxy1 : " + proxy1);		
		
		/*
		 * 产生动态代理类的第二种方法
		 */
		Collection proxy2 = (Collection) constructor.newInstance(new InvocationHandler() {

			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				return null;
			}
			
		});		
		
		System.out.println("proxy2 : " + proxy2);		
	}
}

 

 

以下代码演示如何使动态生成的类成为目标类的代理类

import java.lang.reflect.Method;

public interface Advice {
	void beforeMethod(Method method);
	void afterMethod(Method method);
}

 

import java.lang.reflect.Method;

public class MyAdvice implements Advice {
	long startTime = 0;
	long endTime;
	
	@Override
	public void afterMethod(Method method) {		
		System.out.println("程序结束了");
		endTime = System.currentTimeMillis();
		System.out.println(method.getName() + " 运行了" + (endTime - startTime));
	}

	@Override
	public void beforeMethod(Method method) {		
		System.out.println("程序开始了");
		startTime = System.currentTimeMillis();		
	}
}

 

 

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;

public class CopyOfProxyTest {
	public static void main(String[] args) throws Exception {		
		final ArrayList target = new ArrayList();
		//获得一个Collection的代理类
		Collection proxy = (Collection) getProxy(target, new MyAdvice());
		
		//proxy对应invoke方法中的proxy参数
		//add对应invoke方法中的method参数
		//"aaa"对应invoke方法中的args参数
		proxy.add("aaa");
		proxy.add("bbb");
		proxy.add("ccc");
		
		System.out.println(proxy.size());
	}

	//获得代理
	private static Object getProxy(final Object target, final Advice advice) {
		Object proxy = Proxy.newProxyInstance(
				//目标类的类加载器
				target.getClass().getClassLoader(),  				
				//与目标实现相同的接口
				target.getClass().getInterfaces(),
				new InvocationHandler() {					
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {						
						advice.beforeMethod(method); //在调用目标类之前执行的方法
						Object retVal = method.invoke(target, args);
						advice.afterMethod(method);	 //在调用目标类之后执行的方法			
						return retVal;
					}
				});
		return proxy;
	}
}

  

----------------------android培训java培训、java学习型技术博客、期待与您交流!----------------------

 

详情请查看:http://edu.csdn.net/heima

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics