最近学习了Java动态代理,现在想做个学习总结,具体如下:
代理对象存在的价值:是主要用于拦截对真实业务对象的访问。
为了方便理解,以一个现实生活的案例为例子:
比如明星都会有经纪人,经纪人的作用就和代理类似,要找明星代言,邀请明星出席活动,都需要先联系经纪人,跟经纪人商量具体事宜,如何收费等等。
所以,首先在eclipse中创建一个明星类:
1 public class MingXing implements Person{ 2 public void sing(){ 3 System.out.println("收了费明星唱歌了"); 4 } 5 6 public void dance(){ 7 System.out.println("收了费明星跳舞了"); 8 } 9 }
接着创建明星的经纪人:
1 public class MingXingProxy { 2 //在类中声明要代理的对象,在Java中要求实现代理的对象必须要实现一个接口,所以我们让明星类抽取一个Person接口 3 //经纪人代理的是明星的业务,所以创建一个明星对象,并私有化 4 private Person mx = new MingXing(); 5 public Person createProxy(){ 6 //创建代理对象,这里是固定写法,实现InvocationHandler类中的抽象方法invoke 7 return (Person)Proxy.newProxyInstance(MingXingProxy.class.getClassLoader(),mx.getClass().getInterfaces(),new InvocationHandler(){ 8 //方法中实现被代理对象调用方法需执行的操作,比如邀请明星唱歌,需要收出场费1W,收费1W这个动作在invoke方法中实现 9 /* 10 * proxy:把代理对象自身传递进来 11 * method:代表当前调用的方法 12 * agrs:调用方法的参数 13 */ 14 @Override 15 public Object invoke(Object proxy, Method method, Object[] args) 16 throws Throwable { 17 //获取调用方法的名称 18 String methodname = method.getName(); 19 //判断 20 if(methodname.equals("sing")){ 21 System.out.println("出场费1W"); 22 //收了出场费后,使用method调用对应方法,把明星对象传进来,执行明星唱歌方法 23 method.invoke(mx, args); 24 }else if(methodname.equals("dancing")){ 25 System.out.println("出场费2W"); 26 method.invoke(mx, args); 27 }else { 28 System.out.println("不支持该业务"); 29 } 30 return null; 31 } 32 33 }); 34 } 35 }
明星类抽取的Person接口:
1 public interface Person { 2 void sing(); 3 void dance(); 4 }
编写测试方法:
1 public class ProxyDemo { 2 //测试代理 3 public static void main(String[] args) { 4 //公司举办演出,想在想邀请某明星出席唱歌,不能直接找到明星本人,而需要先找他/她的经纪人 5 MingXingProxy mxProxy = new MingXingProxy(); 6 Person person = mxProxy.createProxy(); 7 person.sing(); 8 } 9 10 }
这样就实现动态代理,代理在实际开发中非常有用,比如我们经常需要编写过滤器解决全站乱码问题,通过传统的包装模式,使用Java已经实现的Request包装类,可以做到重写getParameter方法,但如果在某些应用中Java没有实现包装类,则需要我们自己去实现,实现过程中需要把原有的被包装类内部的所有方法都重写一遍,如果有几十甚至上百个方法要重写,那么将非常麻烦。Java动态代理很美妙的解决了这个问题,通过实现代理对象,直接增强原有类的方法功能。