关于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属性指定了一个已经存在的切点。

时间: 2024-08-24 12:09:11

关于xml配置实现AOP的小知识的相关文章

AOP实现日志打印 基于xml配置的AOP实现 切入点表达式

前置通知,后置通知,异常通知,返回通知 使用注解需要加入 在xml中加入  <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 环绕通知(跟以上结果一样)  需要有返回值return rs: 基于xml配置的AOP实现(上面的注解全去掉,配置以下) ①切入点表达式的语法格式[参见第5章AOP细节] execution([权限修饰符] [返回值类型] [简单类名/全类名] [方法名]([参数列表])) 参见第5章AOP细节:演示验证 1.任

基于XML配置的AOP实现日志打印

Spring中可以使用注解或XML文件配置的方式实现AOP.1.导入jar包 com.springsource.net.sf.cglib -2.2.0.jar com.springsource.org.aopalliance-1.0.0 .jar com.springsource.org.aspectj.weaver-1.6.8 .RELEASE.jar commons-logging-1.1.3. jar spring-aop-4.0.0.RELEASE.jar spring-aspects-

xml配置spring aop

1.spring aop配置如下: 1.aspect切面是一个具体类,里面包含各种执行的通知方法.切面类也要注册到ioc容器中. 2.切入点pointcut,可以在每个通知里单独配置,即每个通知可以指定自己的切入点,各个通知的切入点不必相同. 3.配置aop的层次关系,切面是个具体类,切面里包含通知,切入点.每个通知可以单独指定自己的切入点. 切面是个具体类

[刘阳Java]_Spring AOP基于XML配置介绍_第9讲

基于注解配置的Spring AOP固然简单,但是这节我们会给大家介绍基于XML配置的AOP是如何应用的.为什么这么说了,因为后面我们还会介绍到Spring对Dao操作的事务管理(基于AOP的XML文件方式来配置事务) 1. 基于XML文件方式来配置Spring的AOP,则我们需要的一些基本元素如下 <aop:config.../>,此标签很重要.它是在XML里配置AOP功能的核心标签 all aspect and advisor elements must be placed within a

Spring学习2_AOP通过XML配置简单实现

Spring在实际运用中可通过注解或者XML配置来实现AOP功能,这里在上一篇的基础上通过Demo来模拟XML配置实现AOP的过程. 代码结构如下 1.Spring配置如下,在<aop:config>中配置好对应的切点pointCut, 然后在切面aspect中引用对应的切点即可. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springfra

AOP基础知识及AOP切面编程之注释方法、xml配置方法

<span style="font-family: 微软雅黑; font-size: 10.5pt; letter-spacing: 0pt; ">AOP概念</span> Aspect(切面):它跟类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面是对横切性关注点的抽象 joinpoint(连接点):所谓连接点就是被拦截到的点,在spring中,这些点是方法,因为spring只支持方法类型的连接点,实际上joinpoint还可以是field或类构造器

spring相关—AOP编程—数学计算器情景示例讲解(包含注解配置AOP与XML配置AOP)

1.数学计算器 ①数学计算器接口[MathCalculator]            public void add(int i,int j);     public int sub(int i,int j);     public int multi(int i,int j);     public void divide(int i,int j);    ②提供简单实现:加减乘除运算[EasyImpl]    ③在简单实现的基础上让每一个计算方法都能够打印日志[LoginImpl]    

【Spring】AOP之基于XML配置总结与案例

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 一.AOP的一些概念 AOP(Aspect-Oriented Programming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入封装.继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合.当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力.也就是说,OOP允许你定义从上到下的关系,但

Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AOP编程比较

本篇博文用一个稍复杂点的案例来对比一下基于XML配置与基于AspectJ注解配置的AOP编程的不同. 相关引入包等Spring  AOP编程准备,请参考小编的其他博文,这里不再赘述. 案例要求: 写一个简单的实现四则运算的计算器. 加入AOP功能:日志功能:检测参数中是否有负数的功能. 废话不多说了,直接上代码: (一)基于XML配置: 定义了一个接口类: package com.edu.aop; public interface ArithmeticCalculator { int add(i