关于xml配置实现AOP的小知识
除了前面介绍的基于JDK1.5的注解方式来定义切面,切入点和增强处理外,Spring AOP也允许直接使用XML配置文件来管理它们。在JDK1.5之前,只能使用配置文件的方式来管理,在Spring2.X后提供了一个新的aop命名空间来定义切面、切入点和增强处理。
相比之下,使用XML配置文件方式有如下优点:
如果没有使用JDK1.5以上版本,只能使用XML配置文件的方式
对早期的Spring用于来说更加习惯,而且这种方式允许使用纯粹的POJO来支持AOP
采用XML配置方式时,我们可以清晰的看到系统中存在哪些切面
同时,XML配置文件的方式也有如下缺点:
不能将切面,切入点和增强处理等封装到一个地方。当我们需要查看切面、切点和增强处理时,必须同时结合Java文件和XML配置文件
XML配置文件方式比@AspectJ方式有更多限制:仅支持“singleton”切面Bean,不能在XML中组合多个命名连接点的声明
除此之外,@AspectJ切面还有一个优点就是能被Spring AOP和AspectJ同时支持,如果有一天我们需要将应用改为AspectJ来实现AOP,使用@AspectJ将非常容易迁移。
在Spring的配置文件中,所有的切面、切点和增强处理都必须定义在<aop:config../>元素内部。<beans../>元素可以包含多个<aop:config../>元素,一个<aop:config../>可以包含pointcut、advisor和aspect元素,且这三个元素需要按照此顺序来定义。
注意:当我们使用<aop:config../>方式进行配置时,可能与Spring的自动代理方式相互冲突,因此,建议要么全部使用<aop:config../>配置方式,要么全部使用自动代理方式,不要把两者混合使用。
配置切面
配置<aop:config../>元素时,实质是将已有的Spring Bean转换成切面Bean,所以需要先定义一个普通的Spring Bean。因为切面Bean可以当成一个普通的Spring Bean来配置,所以我们完全可以为该切面Bean配置依赖注入。当切面Bean的定义完成后,通过<aop:congig../>元素中是哟个ref属性来引用该Bean,就可以将该Bean转换成切面Bean了。配置<aop:config../>元素时可以指定如下三个属性:
id:该切面Bean的标识名
ref:指定将要被转换成切面Bean的的普通Bean的id
order:指定该切面Bean的优先级,值越小,优先级越高
如下配置片段定义了一个切面:
<!-- 定义普通的Bean实例 -->
<bean id="afterAdviceBean" class="com.abc.advice.AfterAdviceBean" />
<aop:config>
<!-- 将容器中的afterAdviceBean转换成切面Bean -->
<aop:aspect id="afterAdviceAspect" ref="afterAdviceBean">
...
</aop:aspect>
</aop:config>
上面的配置中,将一个AfterAdviceBean类型普通的Bean对象afterAdviceBean转换成了切面Bean对象afterAdviceAspect。
配置增强处理
与使用@AspectJ完全一样,使用XML一样可以配置Before、After、AfterReturning、AfterThrowing和Around 5种增强处理,而且完全支持和@Aspect完全一样的语义。使用XML配置增强处理分别依赖于如下几个元素:
<aop:before../>:配置Before增强处理
<aop:after../>:配置After增强处理
<aop:after-returning../>:配置AfterReturning增强处理
<aop:after-throwing../>:配置AfterThrowing增强处理
<aop:around../>:配置Around增强处理
这些元素都不支持使用子元素,但通常可以指定如下属性:
pointcut:指定一个切入点表达式,Spring将在匹配该表达式的连接点织入增强处理
pointcut-ref:指定一个已经存在的切入点名称,通常pointcut和pointcut-ref只需使用其中之一
method:指定一个方法名,指定切面Bean的该方法作为增强处理
throwing:只对<aop:after-throwing../>元素有效,用于指定一个形参名,AfterThrowing增强处理方法,可通过该形参访问目标方法所抛出的异常
returning:只对<aop:after-returning../>元素有效,用于指定一个形参名,AfterThrowing增强处理方法,可通过该形参访问目标方法的返回值
既然选择XML配置文件的方式来管理切面、切点和增强处理,那么切面类里定义切面,切点和增强处理的注解就可以全部删除了。
定义切点时,XML配置方式和@AspectJ注解方式支持完全相同的切点指示符,一样可以支持execution、within、args、this、target和bean等切点提示符。另外,XML配置文件方式也和@AspectJ方式一样支持组合切入点表达式,但XML配置方式不再使用简单的&&、|| 和 ! 作为组合运算符(因为直接在XML文件中需要使用实体引用来表示他们),而是使用如下三个组合运算符:and(相当于&&)、or(相当于||)和not(相当于!)。 下面是一个使用<aop:congig../>的例子,这是把前面的例子中关于切面切点和增强处理的注解去掉后,使用XML配置文件来重新实现这些切面切点的功能:
<bean id="adviceTest" class="com.abc.advice.AdviceTest" />
<aop:config>
<!-- 注意这里可以使用order属性为Aspect指定优先级 -->
<aop:aspect id="firstAspect" ref="adviceTest" order="2">
<!-- @Before切点 -->
<aop:before pointcut="execution(* com.abc.service.*.*(..))"
method="permissionCheck"/>
<!-- @After切点 -->
<aop:after pointcut="execution(* com.abc.service.*.*(..))"
method="releaseResource"/>
<!-- @AfterReturning切点 -->
<aop:after-returning pointcut="execution(* com.abc.service.*.*(..))"
method="log"/>
<!-- @AfterThrowing切点 -->
<aop:after-throwing pointcut="execution(* com.abc.service.*.*(..))"
method="handleException"/>
<!-- @Around切点(多个切点提示符使用and、or或者not连接) -->
<aop:around pointcut="execution(* com.abc.service.*.*(..)) and args(name,time,..)"
method="process"/>
</aop:aspect>
</aop:config>
上面的定义中,特意为firstAspec指定了order=2,表明firstAspect的优先级为2,如果这个XML文件中还有order=1的Aspect,那么这个Aspect将被Spring AOP优先织入。其执行结果,和前面几篇文章中介绍的相同,这里不再给出。
配置切点
在Spring中通过<aop:pointcut../>元素来定义切点。当把<aop:pointcut../>元素作为<aop:config../>的子元素时,表明该切点可以被多个切面共享;当把<aop:pointcut../>元素作为<aop:aspect../>的子元素时,表明该切点只能在这个切面内使用。配置<aop:pointcut../>时,通常需要配置如下两个属性:
id:指定该切点的标识名
expression:指定该切点关联的切点表达式
如下的配置定义了一个简单的切点:
<aop:pointcut id="point1" expression="execution(* com.abc.service.*.*(..))" />
另外,如果程序中已经使用注解的方式定义了切点,在<aop:pointcut../>元素中指定切入点表达式时还有另一种用法,看例子:
<aop:pointcut id="point2" expression="com.abc.service.AdviceTest.myPointcut()" />
下面的程序中定义了一个AfterThrowing增强处理,包含该增强处理的切面类如下:
package com.abc.advice;
public class AfterThrowingAdviceTest {
//定义一个普通方法作为增强处理方法,这个方法名将在XML配置文件中指定
public void doRecoveryAction(Throwable th) {
System.out.println("目标方法抛出异常:" + th);
System.out.println("模拟数据库事务恢复");
}
}
与前面的切面类完全类似,该Java类就是一个普通的Java类。下面的配置文件将负责配置该Bean实例,并将该Bean转换成切面Bean:
<bean id="afterThrowingAdviceTest"
class="com.abc.advice.AfterThrowingAdviceTest" />
<aop:config>
<!-- 这个切点将可以被多个<aop:aspect../>使用 -->
<aop:pointcut id="myPointcut"
expression="execution(* com.abc.service.*.*(..))" />
<!-- 这个aspect由上面的Bean afterThrowingAdviceTest转化而来 -->
<aop:aspect id="aspect1" ref="afterThrowingAdviceTest">
<!-- 定义一个AfterThrowing增强处理,指定切入点以切面Bean中
的doRecoverryAction作为增强处理方法 -->
<aop:after-throwing pointcut-ref="myPointcut"
method="doRecoveryAction" throwing="th" />
</aop:aspect>
</aop:config>
上面的<aop:pointcut../>元素定义了一个全局的切点myPointcut,这样其他切面Bean就可以多次复用这个切点了。<aop:after-throwing../>元素中,使用pointcut-ref属性指定了一个已经存在的切点。
关于xml配置实现AOP的小知识的更多相关文章
- 使用Spring框架入门三:基于XML配置的AOP的使用
一.引入Jar包 <!--测试1使用--> <dependency> <groupId>org.springframework</groupId> &l ...
- Spring使用AspectJ注解和XML配置实现AOP
本文演示的是Spring中使用AspectJ注解和XML配置两种方式实现AOP 下面是使用AspectJ注解实现AOP的Java Project首先是位于classpath下的applicationC ...
- Spring XML配置实现AOP
1: 首先我们要定义 配置成切面的类 package cn.gbx.example; import org.aspectj.lang.ProceedingJoinPoint; import org. ...
- 基于XML配置的AOP实现日志打印
Spring中可以使用注解或XML文件配置的方式实现AOP.1.导入jar包 com.springsource.net.sf.cglib -2.2.0.jar com.springsource.org ...
- 一步一步深入spring(6)--使用基于XML配置的spring实现的AOP
上节我们提到了使用基于注解实现的AOP,这节我们将用基于xml配置的方式来实现的AOP. 1.首先建立一个类,作为切面类,这个类主要用来实现注解中各种通知要实现的方法. package com.yan ...
- [刘阳Java]_Spring AOP基于XML配置介绍_第9讲
基于注解配置的Spring AOP固然简单,但是这节我们会给大家介绍基于XML配置的AOP是如何应用的.为什么这么说了,因为后面我们还会介绍到Spring对Dao操作的事务管理(基于AOP的XML文件 ...
- Spring框架学习之注解配置与AOP思想
上篇我们介绍了Spring中有关高级依赖关系配置的内容,也可以调用任意方法的返回值作为属性注入的值,它解决了Spring配置文件的动态性不足的缺点.而本篇,我们将介绍Spring的又一大核心 ...
- Spring学习之旅(八)Spring 基于AspectJ注解配置的AOP编程工作原理初探
由小编的上篇博文可以一窥基于AspectJ注解配置的AOP编程实现. 本文一下未贴出的相关代码示例请关注小编的上篇博文<Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AO ...
- SpringInAction--XML配置Spring Aop
前面学习了如何用注解的方式去配置Spring aop,今天把XML配置的方法也看了下,下面顺便也做了个记录 先把spring中用xml配置aop的配置元素给贴出来: <aop:advisor&g ...
随机推荐
- Android隐藏状态栏、导航栏
Android隐藏状态栏.导航栏 private void hideStatusNavigationBar(){ if(Build.VERSION.SDK_INT<16){ this.getWi ...
- JAVA用途
在现今阶段,最有前途的开发语言当属Java,Java语言是跨平台的,Write Once,Run Anywhere是Java的一句口号,学Application编程,可以在计算机上写程序,学Apple ...
- Timer的故事----Jdk源码解读
咱们今天也来说说定时器Timer Timer是什么? Timer n. [电子] 定时器:计时器:计时员 从翻译来看,我们可以知道Timer的本意是,定时定点. 而JDK中Timer类也的确是这个本 ...
- WebAPI使用多个xml文件生成帮助文档
一.前言 上篇有提到在WebAPI项目内,通过在Nuget里安装(Microsoft.AspNet.WebApi.HelpPage)可以根据注释生成帮助文档,查看代码实现会发现是基于解析项目生成的xm ...
- jQuery 获取当前节点的html包含当前节点的方法
在开发过程中,jQuery.html() 是获取当前节点下的html代码,并不包含当前节点本身的代码,然后我们有时候确需要,找遍jQuery api文档也没有任何方法可以拿到. 看到有的人通过pare ...
- Java线程:线程的同步与锁
一.同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. public ...
- 写个shell脚本
以前更新网站程序都是手动噼里啪啦敲代码,即麻烦又慢,还神经紧张.终于忍不住写个shell脚本. cd /usr/local/tomcat7/apache-tomcat-9.0.0.M4/ bin/ ...
- [SQL入门级] 上篇被移出园子首页,那这篇咱就'薄利多销'
这个系列的博文知识回顾sql知识作的记录,温故而知新.上一篇内容达不到知识分享的层级被移出园子首页,对不住各位看官,内容简单了些.下面咱就记录多一些的基础知识,薄利多销: 控制用户权限 • 创建用户 ...
- MiniUI中DataGrid数据的载入
本文将介绍一下,在ASP.NET MVC环境下,如何用Jquery MiniUI中的Datagrid控件载入数据. 1.效果展示: 2.具体步骤: 1> 既然是在MVC里,那我们的界面自然选择 ...
- Spring学习笔记之四----基于Annotation的Spring AOP编程
你能使用@Aspect annotation将某个Java类标注为Aspect,这个Aspect类里的所有公有方法都可以成为一个Advice,Spring提供了5个Annotation去将某个方法标注 ...