[黑马程序员]第十一篇:代理


----------------------------------- android培训 java培训 、期待与您交流! --------------------------------------


代理在java技术中起着很重要的作用,Spring的aop及各种开源框架都使用了代理的技术。

代理一般分为:静态代理和动态代理。

应用中,一般使用组合代理。

静态代理


public class SetProxyFactory {
	@SuppressWarnings("unchecked")
	public static <T> T getProxy(final T obj) {
		// 类加载器、类的接口、一个InvocationHandler实现
		return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
				.getClass().getInterfaces(), new InvocationHandler() {
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				System.out.println("Start....");
				return method.invoke(obj, args);
			}
		});
	}
	public static void main(String[] agrs) throws ClassNotFoundException {
		Set<String> set = new HashSet<String>();// 创建一个类
		Set<String> proxySet = SetProxyFactory.getProxy(set);// 有类生成一个代理对象
		System.out.println(Proxy.getInvocationHandler(proxySet));
		System.out.println(proxySet.size());
	}
}

动态代理主要涉及到 Proxy类与InvocationHandler类

  1. Proxy有一个 public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)返回值是一个由JVM动态生成的类所实例化的对象,可以认为InvocationHandler 是这个类的变量属性。
  2. loader是类加载器
  3. interfaces 是接口列表
  4. InvocationHandler 是一个InvocationHandler 的实例。
  5. InvocationHandler有一个接口: public Object invoke(Object proxy, Method method, Object[] args)  throws Throwable;此接口可以认为是回调函数,也就是代理的类的对象 被访问时候,就会触发它所绑定的 InvocationHandler 的invoke方法。传来的差数有代理类,方法,差数列表。在invoke方法一般有method.invoke(obj, args)调用,obj真正的实例。

动态关键类还是Proxy类的newProxyInstance方法

public static Object newProxyInstance(ClassLoader loader,
					  Class<?>[] interfaces,
					  InvocationHandler h)
	throws IllegalArgumentException
    {
	if (h == null) {
	    throw new NullPointerException();
	}

	/*
	 * Look up or generate the designated proxy class.
	 */
	Class cl = getProxyClass(loader, interfaces);//关键是创建代理类

	/*
	 * Invoke its constructor with the designated invocation handler.
	 */
	try {
	    Constructor cons = cl.getConstructor(constructorParams);
	    return (Object) cons.newInstance(new Object[] { h });//InvocationHandler是作为一个实例变量传入代理类中。
	} catch (NoSuchMethodException e) {
	    throw new InternalError(e.toString());
	} catch (IllegalAccessException e) {
	    throw new InternalError(e.toString());
	} catch (InstantiationException e) {
	    throw new InternalError(e.toString());
	} catch (InvocationTargetException e) {
	    throw new InternalError(e.toString());
	}
    }

当然使用代理,我们需要注意的有哪些呢?

1、为什么使用代理:主要的目的是为了对目标类,进行精确的控制。比如打打日志

2、为什么用动态代理不用静态代理:用静态代理,如果目标方法改变则需要修改代理类,很不方便。动态代理能避免这个。

3、我们要注意什么?针对接口代理,不能针对类进行动态代理这个也有点遗憾。许多的框架都使用动态代理,debug程序的时候一定要注意。



----------------------------------- android培训 java培训 、期待与您交流! --------------------------------------





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值