Implementations
Spring支持@AspectJ annotation style方法和schema-based方法来实现自定义方面。
基于XML模式
使用常规类以及基于XML的配置来实现方面。
要使用本节中描述的AOP命名空间标记,您需要导入spring 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-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<!-- bean definition & AOP specific configuration -->
</beans>
声明一个方面
使用《aop:aspect》元素声明《aop:aspect》 ,并使用ref属性引用支持bean,如下所示。
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
这里将配置“aBean”并像其他任何Spring bean一样注入依赖项,如前面章节所述。
声明一个PointCut
PointCut有助于确定要用不同建议执行的感兴趣的连接点(即方法)。 在使用基于XML Schema的配置时,PointCut将定义如下 -
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
<aop:PointCut id = "businessService"
expression = "execution(* com.xyz.myapp.service.*.*(..))"/>
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
以下示例定义了一个名为“businessService”的PointCut,它将匹配cn.xnip包下Student类中可用的getName()方法的执行。
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
<aop:PointCut id = "businessService"
expression = "execution(* cn.xnip.Student.getName(..))"/>
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
声明建议
您可以使用元素声明中的五个建议中的任何一个,如下所示。
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
<aop:PointCut id = "businessService"
expression = "execution(* com.xyz.myapp.service.*.*(..))"/>
<!-- a before advice definition -->
<aop:before PointCut-ref = "businessService"
method = "doRequiredTask"/>
<!-- an after advice definition -->
<aop:after PointCut-ref = "businessService"
method = "doRequiredTask"/>
<!-- an after-returning advice definition -->
<!--The doRequiredTask method must have parameter named retVal -->
<aop:after-returning PointCut-ref = "businessService"
returning = "retVal"
method = "doRequiredTask"/>
<!-- an after-throwing advice definition -->
<!--The doRequiredTask method must have parameter named ex -->
<aop:after-throwing PointCut-ref = "businessService"
throwing = "ex"
method = "doRequiredTask"/>
<!-- an around advice definition -->
<aop:around PointCut-ref = "businessService"
method = "doRequiredTask"/>
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
您可以对不同的建议使用相同的doRequiredTask或不同的方法。 这些方法将被定义为方面模块的一部分。
@AspectJ基于
@AspectJ指的是将方面声明为使用Java 5注释注释的常规Java类的样式。 @AspectJ指的是将方面声明为使用Java 5注释注释的常规Java类的样式。 通过在基于XML模式的配置文件中包含以下元素来启用@AspectJ支持。
<aop:aspectj-autoproxy/>
声明一个方面
Aspects类与任何其他普通bean一样,并且可以像任何其他类一样拥有方法和字段,除了它们将使用@Aspect进行注释,如下所示。
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class AspectModule {
}
它们将像任何其他bean一样以XML格式配置,如下所示。
<bean id = "myAspect" class = "org.xyz.AspectModule">
<!-- configure properties of aspect here as normal -->
</bean>
声明一个PointCut
PointCut有助于确定要用不同建议执行的感兴趣的连接点(即方法)。 在使用基于@AspectJ的配置时,PointCut声明有两个部分 -
一个PointCut表达式,它确切地确定我们感兴趣的方法执行。
PointCut签名,包含名称和任意数量的参数。 该方法的实际主体是无关紧要的,实际上应该是空的。
以下示例定义了一个名为“businessService”的PointCut,它将匹配com.xyz.myapp.service包下的类中可用的每个方法的执行。
import org.aspectj.lang.annotation.PointCut;
@PointCut("execution(* com.xyz.myapp.service.*.*(..))") // expression
private void businessService() {} // signature
以下示例定义了一个名为“getname”的PointCut,它将匹配cn.xnip包下Student类中可用的getName()方法的执行。
import org.aspectj.lang.annotation.PointCut;
@PointCut("execution(* cn.xnip.Student.getName(..))")
private void getname() {}
声明建议
您可以使用下面给出的@ {ADVICE-NAME}注释声明五个建议中的任何一个。 这假设您已经定义了PointCut签名方法businessService()。
@Before("businessService()")
public void doBeforeTask(){
...
}
@After("businessService()")
public void doAfterTask(){
...
}
@AfterReturning(PointCut = "businessService()", returning = "retVal")
public void doAfterReturnningTask(Object retVal){
// you can intercept retVal here.
...
}
@AfterThrowing(PointCut = "businessService()", throwing = "ex")
public void doAfterThrowingTask(Exception ex){
// you can intercept thrown exception here.
...
}
@Around("businessService()")
public void doAroundTask(){
...
}
您可以为任何建议定义PointCut内联。 以下是为建议之前定义内联PointCut的示例。
@Before("execution(* com.xyz.myapp.service.*.*(..))")
public doBeforeTask(){
...
}