在Spring的配置文件中,所有切面、切入点和增强处理都必须定义在<aop:config.../>
元素内部。<bean.../>
元素下可以包含多个<aop:config.../>
元素,一个<aop:config>
可以包含pointcut、advisor和aspect元素,且这三个元素必须按照此顺序来定义。关于<aop:config../>
元素所包含的字元素如下图所示。
1)配置切面
定义切面使用上图中的<aop:aspect.../>
元素,使用该元素来定义切面时,其实质是将一个已有的Spring Bean转换成切面Bean,所以需要先定义一个普通的SpringBean。
因为切面Bean可以当成一个普通的Spring Bean来配置,所以我们完全可以为该切面bean配置依赖注入。当切面Bean定义完成后,通过在<aop:aspect.../>
元素中使用ref属性来引用该Bean,就可以将该Bean转换成一个切面Bean了。
配置<aop:aspect.../>
元素时可以指定如下三个属性。
- id:定义该切面的标识名。
- ref:指定以指定ref属性所引用的普通Bean作为切面Bean。
- order:指定该切面bean的优先级,该属性的作用与前边@AspectJ中的@Order Annotation,order属性值越小,该切面对应的优先级越高。
2)配置增强处理
与使用@Aspectj完全一样,使用xml一样可以配置Before、After、AfterReturning、AfterThrowing和Around5种增强处理,而且完全支持和@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:该属性只对
<after-throwing.../>
元素有效,用于指定一个形参名,AfterThrowing增强处理方法可通过该形参访问目标方法所抛出的异常。 - returning:该属性只对
<after-returning.../>
元素有效,用于指定一个形参名,AfterReturning增强处理方法可通过该形参访问目标方法的返回值。
<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<aop:config>
<!-- 将fourAdviceBean转换成切面Bean 切面Bean的新名称为:fourAdviceAspect 指定该切面的优先级为2 -->
<aop:aspect id="fourAdviceAspect" ref="fourAdviceBean" order="2">
<!-- 定义一个After增强处理, 直接指定切入点表达式 以切面Bean中的release()方法作为增强处理方法 -->
<aop:after pointcut="execution(* com.bh.service.impl.*.*(..))"
method="release"/>
<!-- 定义一个Before增强处理, 直接指定切入点表达式 以切面Bean中的authority()方法作为增强处理方法 -->
<aop:before pointcut="execution(* com.bh.service.impl.*.*(..))"
method="authority"/>
<!-- 定义一个AfterReturning增强处理, 直接指定切入点表达式 以切面Bean中的log()方法作为增强处理方法 -->
<aop:after-returning
pointcut="execution(* com.bh.service.impl.*.*(..))" method="log"
returning="rvt"/>
<!-- 定义一个Around增强处理, 直接指定切入点表达式 以切面Bean中的processTx()方法作为增强处理方法 -->
<aop:around pointcut="execution(* com.bh.service.impl.*.*(..))"
method="processTx"/>
</aop:aspect>
<!-- 将secondAdviceBean转换成切面Bean 切面Bean的新名称为:secondAdviceAspect 指定该切面的优先级为1,该切面里的增强处理将被优先织入 -->
<aop:aspect id="secondAdviceAspect" ref="secondAdviceBean" order="1">
<!-- 定义一个Before增强处理, 直接指定切入点表达式 以切面Bean中的authority()方法作为增强处理方法 且该参数必须为String类型(由authority方法声明中msg参数的类型决定) -->
<aop:before
pointcut="execution(* com.bh.service.impl.*.*(..)) and args(aa)"
method="authority" />
</aop:aspect>
</aop:config>
<!-- 定义一个普通组件Bean -->
<bean id="chinese" class="com.bh.service.impl.Chinese" />
<!-- 定义一个普通Bean实例,该Bean实例将被作为Aspect Bean -->
<bean id="fourAdviceBean" class="com.bh.advice.FourAdviceTest" />
<!-- 再定义一个普通Bean实例,该Bean实例将被作为Aspect Bean -->
<bean id="secondAdviceBean" class="com.bh.advice.SecondAdviceTest" />
</beans>
3)配置切入点
Spring提供了<aop:pointcut.../>
元素来定义切入点。当把<aop:pointcut.../>
元素作为<aop:config.../>
的子元素定义时,表明该切入点可被多个切面共享;当把<aop:pointcut.../>
元素作为<aop:aspect.../>
的子元素定义时,表明该切入点只能在对应的切面中有效。
配置<aop:pointcut.../>
元素时通常需要制定如下两个属性。
- id:制定该切入点的标标识名。
- expression:制定该切入点关联的切入点表达式。
<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<aop:config>
<!-- 定义一个切入点:myPointcut
直接指定它对应的切入点表达式 -->
<aop:pointcut id="myPointcut"
expression="execution(* com.bh.service.impl.*.*(..))"/>
<aop:aspect id="afterThrowingAdviceAspect"
ref="afterThrowingAdviceBean" order="1">
<!-- 定义一个AfterThrowing增强处理,指定切入点
以切面Bean中的doRecoveryActions()方法作为增强处理方法 -->
<aop:after-throwing pointcut-ref="myPointcut"
method="doRecoveryActions" throwing="ex"/>
</aop:aspect>
</aop:config>
<!-- 定义一个普通组件Bean -->
<bean id="chinese"
class="com.bh.service.impl.Chinese"/>
<!-- 再定义一个普通Bean实例,该Bean实例将被作为Aspect Bean -->
<bean id="afterThrowingAdviceBean"
class="com.bh.advice.AfterThrowingAdviceTest"/>
</beans>