AOP,即面向切面编程,具体的理论就不多说了,只在这里记下具体的配置文件的写法。
AOP的配置文件分两种风格,一种是使用Schema风格的XML配置,还有一种是在Java 1.5中新引入的使用注解方式的AspectJ,在这里我们先说XML格式的配置文件。
首先需要在AOP命名空间中引入标签如下:
<?xml version="1.0" encoding="UTF-8"?>
<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-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<!-- <bean/> definitions here -->
</beans>
在Spring的配置文件中,所有的切面和通知都必须定义在<aop:config>元素内部。 (一个application context可以包含多个 <aop:config>)。 一个<aop:config>可以包含pointcut,advisor和aspect元素 (注意这三个元素必须按照这个顺序进行声明)。
声明一个切面:
加入了Schema支持后,就可以像定义一个普通的Bean一样定义切面。
切面使用<aop:aspect>来声明,backing bean(支持bean)通过 ref 属性来引用:
<aop:config>
<aop:aspect id="myAspect" ref="aBean">
...
</aop:aspect>
</aop:config>
<bean id="aBean" class="...">
...
</bean>
切面的支持bean(上例中的"aBean")可以象其他Spring bean一样被容器管理配置以及依赖注入。
声明一个切入点
一个描述service层中所有service执行的切入点可以定义如下:<aop:config>
<aop:pointcut id="businessService"
expression="execution(* com.xyz.myapp.service.*.*(..))"/>
</aop:config>
上面的表达式使用了AspectJ切入点表达式语言。
声明通知:
Schema风格和AspectJ风格都支持同样的5种通知类型风格:
1:前置通知:
前置通知在匹配方法执行前运行。在<aop:aspect>中使用<aop:before> 元素来声明它。
<aop:aspect id="beforeExample" ref="aBean">
<aop:before
pointcut-ref="dataAccessOperation"
method="doAccessCheck"/>
...
</aop:aspect>
pointcut-ref当然是上面已经定义好的一个pontcut。Method属性标识了提供通知主体的方法(doAccessCheck)。 这个方法必须定义在包含通知的切面元素所引用的bean中。在一个数据访问操作执行之前 (一个方法执行由切入点表达式所匹配的连接点),切面中的"doAccessCheck"会被调用。
2:后置通知:
后置通知在匹配的方法完全执行后运行。
<aop:aspect id="afterReturningExample" ref="aBean">
<aop:after-returning
pointcut-ref="dataAccessOperation"
method="doAccessCheck"/>
...
</aop:aspect>
3:异常通知:
<aop:aspect id="afterThrowingExample" ref="aBean">
<aop:after-throwing
pointcut-ref="dataAccessOperation"
method="doRecoveryActions"/>
...
</aop:aspect>
4:最终通知:
<aop:aspect id="afterFinallyExample" ref="aBean">
<aop:after
pointcut-ref="dataAccessOperation"
method="doReleaseLock"/>
...
</aop:aspect>
5:环绕通知:
<aop:aspect id="aroundExample" ref="aBean">
<aop:around
pointcut-ref="businessService"
method="doBasicProfiling"/>
...
</aop:aspect>
Advisor:
"advisor"这个概念来自Spring1.2对AOP的支持,而在AspectJ中没有等价的概念。 advisor就像一个小的自包含的切面,这个切面只有一个通知。切面自身通过一个bean表示, 并且必须实现一个在第 7.3.2 节 “Spring里的通知类型”中描述的通知接口。 Advisor可以很好的利用AspectJ的切入点表达式。
Spring 2.0通过<aop:advisor>元素来支持advisor概念。 你将会发现大多数情况下它会和transactional advice一起使用,在Spring 2.0中它有自己的命名空间。其格式如下:
<aop:config>
<aop:pointcut id="businessService"
expression="execution(* com.xyz.myapp.service.*.*(..))"/>
<aop:advisor
pointcut-ref="businessService"
advice-ref="tx-advice"/>
</aop:config>
<tx:advice id="tx-advice">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>