Java动态代理的简单学习

如果把要被代理的对象比喻成演员,那代理对象就是它的经纪人。

经纪人会帮助演员处理很多事情,体现在代码里就是各种各样的方法。

所以说代理对象方便了被代理对象的日后维护和修改,降低了程序的耦合性,提高了程序的鲁棒性。

功能介绍完了,我们来看一下具体的实例:

要实现动态代理,要实现两个重要的类,一个是Proxy——生成代理对象的类,一个是 InvocationHandler——处理被代理对象的类,可以进行自定义。

首先来看一下实现动态代理的格式:

Proxy.newProxyInstance(loader, interfaces, h);

Proxy——用来生成代理对象

newProxyInstance(...)——创建一个Proxy实例

loader——当前类的类加载器

interfaces——被代理对象的所有接口

h——InvocationHandler处理类的实现

从格式上可以看出来,实现动态代理要获取当前类的类加载器,在哪个类中就获取哪个类的加载器即可,还要获取被代理对象的所有接口。

下面通过实例来看一下动态代理的用法:

package cn.itcast_动态代理;

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

public class Demo {
	
	public static void main(String[] args) {
		
		//list是被代理的对象
		final ArrayList list = new ArrayList();
		
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		System.out.println(list);
		
		ArrayList list2 = new ArrayList();
		list.add("xx");
		
		List p = (List)Proxy.newProxyInstance(Demo.class.getClassLoader(), list.getClass().getInterfaces(), 
				
				new InvocationHandler() {
					
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						//System.out.println(proxy.getClass());
						
						//增强add方法
						String name = method.getName();
						//System.out.println(name);
						if("add".equals(name))
						{
							System.out.println("进行添加操作:");
							list.add("***");
							return true;
						}
						
						if("size".equals(name))
						{
							return 0;
						}
						
						if("remove".equals(name))
						{
							throw new UnsupportedOperationException();
						}
						return method.invoke(list, args);
					}
				});
		//代理对象p中与add方法名相同的方法,并非list中原来的add方法,所以结果会返回false
		boolean b = p.add("123");
		System.out.println("添加成功?"+b);
		
		//同理此size方法也是p中的与size同名的方法
		int n = p.size();
		System.out.println("该集合中一共有:"+n+"个元素");
		
		//输出list后,发现list中并非没有元素,而是有四个元素
		System.out.println(list);
		//addAll方法因为没有在p中进行判断,所以没有影响
		p.addAll(list2);
		
		//这里也是p中经过判断的remove方法
		boolean re = p.remove("aaa");
		System.out.println("移除成功?"+re);
	}

}

此处我们把创建的list对象当做被代理对象,按照上面的格式创建Proxy实例后,在InvocationHandler处理类中重写invoke方法,获取list对象的方法名后list对象中的方法就任我们摆布了,在进行判断并对list中的add、size、remove方法进行操作后,我们试着调用一下p对象的add、size和remove方法,控制台会出现这样的结果:

其中,add、size、remove方法的都是按照p对象中判断后的同名方法执行的,而没有进行判断的静态方法addAll还是按照list对象中的原来的功能执行,由此可见,动态代理可以修改被代理对象中的方法,从而降低了程序的耦合性,提高了程序的可维护性。

猜你喜欢

转载自blog.csdn.net/qq_39209361/article/details/81382191