JAVA代理详解

1.什么是动态代理?

答:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实。代理一般会实现它所表示的实际对象的接口。代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统的实际功能,代理对象对客户隐藏了实际对象。客户不知道它是与代理打交道还是与实际对象打交道。

2.为什么使用动态代理?

答:因为动态代理可以对请求进行任何处理

3.使用它有哪些好处?

答:因为动态代理可以对请求进行任何处理

4.哪些地方需要动态代理?

答:不允许直接访问某些类;对访问要做特殊处理等

目前Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。 其实现主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。 

Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现

以下为模拟案例,通过动态代理实现在方法调用前后向控制台输出两句字符串

目录结构:


实例代码:

5、接口

package com.ren.day03;

import java.lang.reflect.Method;

//代理类接口
public interface Advice {
	void beforeMehtod(Method method);
	void afterMehtod(Method method);
}

6、实现了该接口的类

package com.ren.day03;

import java.lang.reflect.Method;

public class MyAdvice implements Advice {
	private long start = 0;
	private long end = 0;
	
	@Override
	public void beforeMehtod(Method method) {
		// TODO Auto-generated method stub
		System.out.println("方法调用前");
		start = System.currentTimeMillis();
	}

	@Override
	public void afterMehtod(Method method) {
		// TODO Auto-generated method stub
		end = System.currentTimeMillis();
		System.out.println(method.getName() + "run time :" + (end - start));
		System.out.println("方法调用后");
	}
}

7、测试类

package com.ren.day03;

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

public class ProxyTest {

	/**
	 * @param args
	 * @throws NoSuchMethodException 
	 * @throws SecurityException 
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws IllegalArgumentException 
	 */
	public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
		// TODO Auto-generated method stub
		Class clazzProxy = Proxy.getProxyClass(
				Collection.class.getClassLoader(), Collection.class);

		System.out.println(clazzProxy.getName());

		System.out.println("---------Begin constructor list---------");
		Constructor[] constructors = clazzProxy.getConstructors();

		for (Constructor constructor : constructors) {
			String name = constructor.getName();
			StringBuilder sb = new StringBuilder(name);
			sb.append("(");

			Class[] clazzParaType = constructor.getParameterTypes();
			for (Class clazzPara : clazzParaType) {
				sb.append(clazzPara.getName());
				sb.append(",");
			}
			if (clazzParaType.length != 0)
				sb.deleteCharAt(sb.length() - 1);
			sb.append(")");
			System.out.println(sb.toString());
		}
		
		System.out.println("---------Begin method list---------");
		Method[] methods = clazzProxy.getMethods();

		for (Method method : methods) {
			String name = method.getName();
			StringBuilder sb = new StringBuilder(name);
			sb.append("(");

			Class[] clazzParaType = method.getParameterTypes();
			for (Class clazzPara : clazzParaType) {
				sb.append(clazzPara.getName());
				sb.append(",");
			}
			if (clazzParaType.length != 0)
				sb.deleteCharAt(sb.length() - 1);
			sb.append(")");
			System.out.println(sb.toString());
		}
		
		System.out.println("-----------Create instance object--------------");
//		clazzProxy.newInstance();
		//得到构造器
		Constructor constructor = clazzProxy.getConstructor(InvocationHandler.class);
		
		//实现InvocationHandler接口
		class MyInvocationHandler implements InvocationHandler {

			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				// TODO Auto-generated method stub
				return null;
			}
			
		}
		//创建实例对象1
		Collection proxy1 = (Collection)constructor.newInstance(new MyInvocationHandler());
		
		//调用方法
		System.out.println(proxy1);
		System.out.println(proxy1.toString());
		//从toString方法可以看出创建实例对象成功,至于打印为什么是null,是因为toString方法返回null
		
		//创建实例对象2,用内部类实现InvocationHandler接口
		Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler() {

			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				// TODO Auto-generated method stub
				return null;
			}
				
		});
		
		
		//创建实例对象3,直接用Rroxy,newProxyInstance方法
		/*Collection proxy3 = (Collection)Proxy.newProxyInstance(
				Collection.class.getClassLoader(), 
				new Class[]{Collection.class}, 
				new InvocationHandler() {
					
					ArrayList target = new ArrayList(); 
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						// TODO Auto-generated method stub
						System.out.println("方法调用前");
						long start = System.currentTimeMillis();
						Object obj = method.invoke(target, args);
						long end = System.currentTimeMillis();
						System.out.println(method.getName() + "run time :" + (end - start));
						System.out.println("方法调用后");
						return obj;
					}
				});*/
		
		final ArrayList target = new ArrayList(); 
		Collection proxy3 = getProxy(target,new MyAdvice());
		
		//再次调用方法
		proxy3.add("fff");
		proxy3.add("fff");
		proxy3.add("fff");
		
		System.out.println(proxy3.size());
	}
	
	//创建实例对象3,直接用Rroxy,newProxyInstance方法
	public static Collection getProxy(final ArrayList target,final Advice advice) {
		Collection proxy3 = (Collection)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.beforeMehtod(method); //通过对象传入方法
						Object obj = method.invoke(target, args);
						advice.afterMehtod(method); 
						return obj;
					}
				});
		return proxy3;
	}

}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值