首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

转载:Spring AOP运用

2012-12-22 
转载:Spring AOP应用[colorindigo]在实际的应用程序开发中,经常需要在一个服务流程中插入一些与业务逻辑

转载:Spring AOP应用
[color=indigo]在实际的应用程序开发中,经常需要在一个服务流程中插入一些与业务逻辑无关的系统服务逻辑(最常见的就是记录日志,权限检查等),如果把所有这些与业务逻辑无关的服务与业务逻辑编织在一起,就会使业务逻辑对象的负担加重,因为它不但要具有业务逻辑的功能,还带有例如记录日志等其他功能,这样就容易产生对象的职责混淆。
为了避免对象职责的混淆,我们在设计中就需要将与业务逻辑无关的服务逻辑从业务逻辑中剥离出来,独立设计为一个模块或对象,而在希望需要使用这些对象的时候插入进来,不希望使用的时候去掉即可,这种设计模式就称为AOP。
Spring AOP是实现AOP的一种技术。Spring AOP最常用的就是采用XML配置文件的方式。Spring AOP只支持在目标对象的某个方法的前后调用服务代码。

在目标对象的方法执行之前调用(Before Adivce)

首先需要定义目标对象必须实现的接口:



现在我们想要在调用对象HelloSpeaker的sayHello()方法前打印一下方法开始执行的日志,一般情况下我们会直接在sayHello()的方法中直接加上日志的代码,这样就把日志和业务逻辑的代码融在了一起,对于要记录大量日志的程序来说,无疑会加重目标对象的负担。
我们把打印日志的代码独立出来成为一个专门用于日志记录的对象,这里需要实现Spring的MethodBeforeAdvice接口:


在before()方法的实现中,加入了一些记录日志的代码,LogBeforeAdive被设计成一个独立的服务,可以提供给需要这个服务的对象,在下面的配置中,我们把这个服务提供给了前面的HelloSpeaker对象:


在上面的配置文件中,属性target指定了要被服务的目标对象为helloSpeaker,属性interceptorNames指定了使用的服务对象是logBeforeAdvice。这样就建立了目标对象与服务对象之间的联系,下面是测试代码:



可以看到,这个服务对象的目的是在执行目标对象的方法之后执行afterReturning()方法打印方法执行完毕的日志。
下一步就是配置XML文件了,把这个服务提供给前面helloSpeaker目标对象:



可以看到,与前面的配置Before Advice非常相似。
测试代码与Before Advice的完全一样,这里不再重复列出。动手试一下,看看是否在执行目标对象的sayHello()方法之后调用了打印结束日志。
当然,还可以把Before Advice和After Advice一起提供给目标对象,这样,就可以在执行目标对象的方法的前、后都打印出日志了,配置如下:



可以看到,在interceptorNames属性中,把logBeforeAdvice和logAfterAdvice两个服务对象都提供给了目标对象,实际上我们可以配置任意多个。
测试代码依然与前面的一样,不再列出,执行一下,看看结果是否是在执行sayHello()方法之前和之后分别打印了日志。



在目标对象的方法执行前后调用(Around Advice)



在前面的两种模式中,有一个缺陷,就是无论如何,目标对象的方法总是会被执行,我们不能控制目标对象的方法是否执行,且执行的时机。
有时候我们需要自行决定是否要执行目标对象的方法,有时需要在不同的时机才执行目标对象的方法,比如权限检查,当权限检查通过时,才继续执行目标对象的方法,如果权限检查不通过,则进入别的流程中。前面的两种模式是做不到这一点的。
在Around Advice这种模式中,我们就可以自行决定是否执行目标对象的方法及其执行的时机了。
这种模式需要实现MethodInterceptor接口:



如上例中,我们在调用proceed()方法的前后打印了日志,则表示在执行helloSpeaker目标对象的sayHello()方法的前后都打印日志。
可以看到,关键就在于proceed()方法的调用,因此,在这种模式中,我们可以在调用proceed()方法的前、后的任何地方插入任何处理逻辑,当然,我们也可以不调用proceed()方法,这样,目标对象的方法就不能执行了。
测试代码与前面的完全一样,这里不再列出。
对于前面的三种方式,我们可以看出,这几种方式都需要在使用时建立代理对象,然后获取代理对象并把类型转换为目标对象的接口,这需要我们手动创建代理对象,即每一个目标对象都要建立一个相应的代理对象,对于有很多目标对象的应用程序,配置XML文件无疑会是一件痛苦的事。
Spring AOP框架中提供了一种自动创建代理的工具。



自动代理(BeanNameAutoProxyCreator)



要使用Spring AOP的自动代理,需要使用org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator类来完成。
这里,目标对象依然使用前面的helloSpeaker,服务对象依然使用前面的LogInterceptor,代码不再列出,下面是配置自动代理的XML文件:



在上面的配置中,指定了org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator类的两个属性,beanNames和interceptorNames,beanNames指定了要进行自动代理的目标对象,interceptorNames与前面的几种模式中的这个属性含义相同,指定了提供服务的对象。
测试代码为:


下面在XML文件中增加对helloSpeaker2目标对象提供服务:



在beanNames属性中增加了helloSpeaker2目标对象,因此logInterceptor也对它提供服务。我们还可以增加任意多的目标对象。
同样,我们也可以为目标对象提供多个服务对象,下面我又定义了一个agumentInterceptor服务对象:



下面在XML文件中增加agumentInterceptor服务对象:



在interceptorNames属性中增加了agumentInterceptor服务对象,这样,agumentInterceptor服务就可以在目标对象上被应用了。
5.结束语
以上就是Spring AOP提供的几种比较简单且常用的模式,当然,Spring还提供了很多其他的方式,这里不再一一列出。一般情况下,自动代理的模式是我们经常使用的,它的配置很灵活,我认为初学只要能掌握并使用这种模式就可以了。

本文来自:http://blog.csdn.net/ganglong99/article/details/3942726[/color]

热点排行