好吧,我承认,这个博客的名称都是有点问题的。因为笔者这个时候也有点混沌,但是我坚信这个应该是在将要质变的时候才会有的状态。
步入正文:反射和动态代理的区别。
动态代理,代理,前面已经有一篇文章说了他们的用法,http://blog.csdn.net/wltsysterm/article/details/64437634。
我们也都知道,动态代理其实用到了反射。那么笔者还是想论述下初学者可能会进入的一个理解误区,因为我进入了,所以我就拿出来跟大家共享下。
误区:为啥用动态代理不用反射
1、网上其他论坛或者是博友已经有好多文章论述为啥使用动态代理,动态代理有什么作用。
笔者这边也简单的帮忙概括下:
1)动态代理,struts的拦截器用到,spring的aop用到,用动态代理可以增强委托类的方法,增强体现在:事物的统一控制,统一日志控制等
2)解耦:实际调用的是代理类,实现调用处和委托类解耦(我的理解是:实现同一日志调用和委托类解耦)
3)隐藏底层代码:只暴露出代理类给我们,委托类可以隐藏起来(这块内容有点牵强)
比如有一些底层的代码,我们不想显示出源码,这个时候可以生成一个代理类,把这个代理类和要被调用的方法暴露出来,就可以实现调用委托类某个方法。
上面这些作用直接通过反射可以做到吗
好吧,答案是既可以又不可以。
下面附上笔者理解过程写的代码
String classfullpath = propertiesUtil.readValue(urlarr[0]);
Class c = Class.forName(classfullpath);//获取到委托类的类
//实例化对象
Object target = c.newInstance();
//反射调用方法,并返回值
Systerm.out.println("before say hello");
//这边要求调用的方法的参数类型,参数个数都要知道
Method action = c.getMethod(urlarr[1], new Class[]{String.class});
obj = action.invoke(target , new Object[]{param});
Systerm.out.println("after sya hello");
看到这边大家觉得,好像可以产生统一日志的功能,但是其实不然,上面如果只是告诉我们委托类对象和要调用的方法,是不足以完成方法的调用,还需要参数类型和参数个数
,但是每个方法的参数类型和参数个数其实都是不一样的,所以这个实现是有点难处的。
总结,反射是不能直接坐到动态代理的功能的。
再说下动态代理,以cglib动态代理为例子,人家是通过子类调用父类实现方法调用。而且方法的调用是显示调用的,即调用哪个方法,这个方法的参数有哪些都是清楚的,所以人家重心其实还是放在方法增强功能上,通过写一个动态代理中介类,实现所有想要增强的委托类的方法增强,这点,单纯的反射是做不到的。