代理模式

    代理模式是在不改变源码的情况下增加已有方法的功能。要使用代理模式的前提是:被代理的类实现了一个接口。代理模式分为静态代理模式与动态代理模式。

   静态代理模式:

          只是在实现与被代理类相同的接口,在代理对象力穿一个被代理类的对象。具体实现如下代码:

 

class ProxyList implements List<String>{

	List<String> target;

	public ProxyList(List<String> target) {
		this.target = target;
	}


	@Override
	public boolean add(String e) {
		Thread t = Thread.currentThread();
		System.out.println("线程"+t.getName()+"调用add"); 
		return target.add(e); 
	}

	@Override
	public void add(int index, String element) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean addAll(Collection<? extends String> c) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean addAll(int index, Collection<? extends String> c) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void clear() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean contains(Object o) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean containsAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public String get(int index) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int indexOf(Object o) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Iterator<String> iterator() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int lastIndexOf(Object o) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public ListIterator<String> listIterator() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ListIterator<String> listIterator(int index) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean remove(Object o) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public String remove(int index) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean removeAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean retainAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public String set(int index, String element) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int size() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public List<String> subList(int fromIndex, int toIndex) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object[] toArray() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <T> T[] toArray(T[] a) {
		// TODO Auto-generated method stub
		return null;
	}
	
}


上面的代码是list集合的一个静态代理类,在这个类力只是实现了一个add方法,其他方法只要增加一定的功能和调用target对象相应的方法就可以。

 

动态代理:

         java 提供了动态代理API:

           1     底层是利用反射实现的功能

           2     java 提供了API Proxy,动态的继承接口(被代理类所实现的接口),实现接口中所有的方法,当方法被调用时候,将调用请求转给调用处理器处理

           3     调用处理器,就可以处理所有的方法执行过程

    下面代码是list集合的动态代理的实现以及与之的实现:

  

public List proxy(final List list){
		//调用处理器
		InvocationHandler handler = new InvocationHandler() {
			//invoke 调用
			//当有方法被调用时候执行invoke 方法,
			// 参数proxy是代理对象, method正在执行的方法, args是调用方法传递的参数
			// 返回值是方法执行的结果
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				Thread t = Thread.currentThread();
				System.out.println("线程"+t.getName()+"调用"+method.getName());
				//根据业务规则决定是否执行 被代理方法 method.invoke(list, args);
				//在这里可以添加业务逻辑
				//if(没有授权) throw 权限不够异常
				//if(没有登陆) throw 需要登陆异常
				//方法调用之前的 可以添加逻辑
				Object val = method.invoke(list, args);
				//方法调用之后的 可以添加逻辑
				// 返回值太大 超过范围,抛出权限不够 。。。
				return val;
			}
		};
		/*
		 * 创建代理类对象
		 * Proxy.newProxyInstance 根据接口  getClass.getClassLoader:获取一个类加载器(任何一个类加载器都可以),
		 * new Class[]{List.class}:必须是接口 ,  handler :将一个处理器传给代理类,以便在代理类中调用handler中的invoke方法。   
		 * List.class 创建对象,也就是实现了接口的全部方法
		 * 当调用了这些方法时候,就会执行 调用处理器中的 invoke方法,并且当前方法作为参数 method
		 * 传递给 invoke 方法,在invoke方法可以利用 method.invoke()执行方法。
		 */
		List proxy = (List) Proxy.newProxyInstance(getClass().getClassLoader(), 
				new Class[]{List.class}, handler);
		return proxy;
	}
}


测试代理类对象的方法:

 

public void testProxy3(){
		List<String> list = new ArrayList<String>();
		list = proxy(list);
		list.add("Tom");
		list.add("Jerry");
		list.remove("Tom");
	}


代理模式的图片分析:

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值