读书人

Spring AOP(一):JDK动态代理

发布时间: 2012-10-13 11:38:17 作者: rapoo

Spring AOP(1):JDK动态代理
声明:本文取材于《精通Spring2.x》上的经典例子。

要了解Spring AOP,建议先熟悉一下设计模式中的代理模式(不基于编程语言的代理模式,关键是理解其思想)。

场景:在各个业务方法中添加进行方法性能测试的逻辑,输出测试方法性能信息(比如运行所花费的时间)。
本例假设业务为ForumServiceImpl,它实现了ForumService接口,该接口提供两个业务操作,见代码:


ForumService target = new ForumServiceImpl();PerformanceHandler handler = new PerformanceHandler(target);ForumService proxyForum = (ForumService)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);proxyForum.removeForum(1);proxyForum.removeTopic(200);

此处,Proxy.getProxyInstance方法根据目标类的类加载器和所实现的接口,实现了基于特定InvocationHandler的代理对象,后面的操作中我们就可以透明的使用代理对象进行业务逻辑操作了。

问题总结:
动态代理对目标类中所有的方法都进行了拦截!如果此时ForumService加入了一个简单方法无需进行性能测试,也逃不过InvocationHandler的拦截。当然,可以在invoke方法中加入简单判断:if(method.getName().equals(targetMethod)){...},
这样就可以对目标对象的目标方法进行区别对待。另外,AOP对此提供了更好的解决办法:IntroductionInterceptor。从target.getClass().getInterfaces()可以看出,JDK动态代理需要目标对象必须实现一定的接口,如果此例中我们ForumServiceImpl不实现ForumService接口呢?那么通过Proxy获得代理对象的代码将出现异常,异常描述类似于:$Proxy0 can't be cast to...即类型转换错误。这点cglib做得很成功。JDK动态代理是每次在使用代理对象时动态的改变目标类的信息,因此使用代理对象时执行效率受到了影响,这点cglib占有优势。

读书人网 >软件架构设计

热点推荐