基于Schema的AOP

上篇文章我们讲到了使用注解的形式来使用Spring AOP。本文我们介绍如何使用XML Schema的形式使用Spring AOP。

要想使用本文的AOP命名空间标记,需要导入xmlns:aop=“http://www.springframework.org/schema/aop”。

在Spring配置中,所有Aspect和Advisor元素都必须放在aop:config元素中(在应用程序上下文配置中可以有多个aop:config元素)。aop:config元素可以包含pointcut、advisor和aspect元素(请注意,这些元素必须按该顺序声明)。

定义Aspect

一个aspect是定义在Spring应用程序上下文的java bean对象。

你可以使用aop:aspect元素声明一个方面,并使用ref属性引用相应的bean,如下示例所示:

    <aop:config>
<aop:aspect id="concurrentOperationRetry" ref="concurrentOperationExecutor">
</aop:aspect>
</aop:config> <bean id="concurrentOperationExecutor"
class="com.flydean.aspect.ConcurrentOperationExecutor">
<property name="maxRetries" value="3"/>
<property name="order" value="100"/>
</bean>

定义Pointcut

你可以在aop:config中使用aop:pointcut来定义一个Pointcut,如下所示:

    <aop:config>
<aop:pointcut id="idempotentOperation"
expression="execution(* com.flydean.service.*.*(..))
and
@annotation(com.flydean.beans.Idempotent)"/> </aop:config>

定义在顶层aop:config中的aop:pointcut可以在多个aspects和advisors之间共享。

当组合切入点子表达式时,可以使用and、or和not关键字来代替&& || 和!,如下所示:

 <aop:pointcut id="businessService"
expression="execution(* com.xyz.myapp.service.*.*(..)) && this(service)"/>
   <aop:pointcut id="businessService"
expression="execution(* com.xyz.myapp.service.*.*(..)) and this(service)"/>

定义Advice

schema-based AOP 支持使用与@Aspectj样式相同的五种建议,它们具有完全相同的语义。

Before Advice

在匹配的方法执行之前运行通知。它通过在aop:aspect中声明使用的aop:before元素,如下示例所示:

    <aop:before
pointcut-ref="dataAccessOperation"
method="doAccessCheck"/>

After Returning Advice

After Returning Advice,在匹配的方法执行正常完成时运行。它在一个aop:aspect中声明,方式与之前的通知相同。下面的示例演示如何声明它:


<aop:after-returning
pointcut-ref="dataAccessOperation"
method="doAccessCheck"/>

正如在@Aspectj样式中一样,您可以在通知正文中获得返回值。为此,请使用returning来指定应将返回值传递到的参数的名称,如下示例所示:

   <aop:after-returning
pointcut-ref="dataAccessOperation"
returning="retVal"
method="doAccessCheck"/>

doAccessCheck方法必须要有声明名为retval的参数。如下所示:

public void doAccessCheck(Object retVal) {...

After Throwing Advice

当匹配的方法引发异常退出时执行。它通过在aop:aspect中声明after-throwing 元素来实现,如下示例所示:

    <aop:after-throwing
pointcut-ref="dataAccessOperation"
method="doRecoveryActions"/>

同样的,你可以在通知方法中获得抛出的异常,如下所示:

    <aop:after-throwing
pointcut-ref="dataAccessOperation"
throwing="dataAccessEx"
method="doRecoveryActions"/>

doRecoveryActions方法必须有声明名为DataAccessEx的参数,如下所示:

public void doRecoveryActions(DataAccessException dataAccessEx) {...

After (Finally) Advice

无论匹配的方法执行如何退出,after(finally)通知都会运行。可以使用after元素声明它,如下示例所示:

   <aop:after
pointcut-ref="dataAccessOperation"
method="doReleaseLock"/>

Around Advice

最后一种advice是around advice的。around通知运行“around”匹配的方法执行。它有机会在方法执行之前和之后都进行工作,并确定何时、如何以及该方法真正开始执行。

你可以使用aop:around元素来声明around advice。advice方法的第一个参数必须是ProceedingJoinPoint类型。

   <aop:around
pointcut-ref="businessService"
method="doBasicProfiling"/>

doBasicProfiling advice的实现如下:

public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}

advice参数

如果您希望显式地为advice方法指定参数名,可以使用advice元素的arg-names属性来指定参数名,下面是例子:

    <aop:config>
<aop:aspect ref="profiler"> <aop:pointcut id="theExecutionOfSomePersonServiceMethod"
expression="execution(* com.flydean.service.PersonService.getPerson(String,int))
and args(name, age)"/> <aop:around pointcut-ref="theExecutionOfSomePersonServiceMethod"
method="profile"/> </aop:aspect>
</aop:config>

相应的aspect bean定义如下:

public class SimpleProfiler {

    public Object profile(ProceedingJoinPoint call, String name, int age) throws Throwable {
StopWatch clock = new StopWatch("Profiling for '" + name + "' and '" + age + "'");
try {
clock.start(call.toShortString());
return call.proceed();
} finally {
clock.stop();
System.out.println(clock.prettyPrint());
}
}
}

profile接收两个参数。

Advisors

“Advisors”的概念来自于Spring中定义的AOP支持,在AspectJ中没有直接的等价物。Advisors就像一个独立的小方面,只有一条advice。

Spring使用aop:advisor元素支持Advisor概念。您通常会看到它与事务性advice结合使用,后者在Spring中也有自己的名称空间支持。以下示例展示了advisor:

<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>

本文的例子可以参考aop2

更多教程请参考 flydean的博客

Spring5参考指南:基于Schema的AOP的更多相关文章

  1. Spring5参考指南:基于注解的容器配置

    文章目录 @Required @Autowired @primary @Qualifier 泛型 @Resource @PostConstruct和@PreDestroy Spring的容器配置可以有 ...

  2. Spring5参考指南:IOC容器

    文章目录 为什么使用Spring5 什么是IOC容器 配置元数据 实例化容器 XML嵌套 groovy bean定义DSL 使用容器 最近在翻译Spring Framework Documentati ...

  3. 基于Schema的AOP 配置使用详解

    原文地址:http://jinnianshilongnian.iteye.com/blog/1418598 基于Schema的AOP从Spring2.0之后通过"aop"命名空间来 ...

  4. 开涛spring3(6.3) - AOP 之 6.3 基于Schema的AOP

    6.3  基于Schema的AOP 基于Schema的AOP从Spring2.0之后通过“aop”命名空间来定义切面.切入点及声明通知. 在Spring配置文件中,所以AOP相关定义必须放在<a ...

  5. spring aop 基于schema的aop

    AOP的基本概念: 连接点(Jointpoint):表示需要在程序中插入横切关注点的扩展点,连接点可能是类初始化.方法执行.方法调用.字段调用或处理异常等等,Spring只支持方法执行连接点,在AOP ...

  6. spring3: 基于Schema的AOP

    6.3  基于Schema的AOP 基于Schema的AOP从Spring2.0之后通过“aop”命名空间来定义切面.切入点及声明通知. 在Spring配置文件中,所以AOP相关定义必须放在<a ...

  7. Spring5参考指南:AOP代理

    文章目录 AOP代理 AOP Proxies原理 AOP代理 通常来说Spring AOP有两种代理方式,一种默认的JDK代理,只能代理接口,一种是CGLIB代理,可以代理具体的类对象. Spring ...

  8. 第三章 AOP 基于Schema的AOP

    基于Schema定义的切面和前现两种方式定义的切面,内容上都差不多,只是表现形式不一样而已. 3.7.1一般增强的使用 a.目标类 public class Target { public void ...

  9. Spring5参考指南:Bean作用域

    文章目录 Bean作用域简介 Singleton作用域 Prototype作用域 Singleton Beans 中依赖 Prototype-bean web 作用域 Request scope Se ...

随机推荐

  1. 3.26java作业

    1.编写程序, 输入变量x的值,如果是1,输出x=1,如果是5,输出x=5,如果是 10,输出 x=10,除了以上几个值,都输出x=none.(知识点:if条件语句) package fda; imp ...

  2. 从 Socket 编程谈谈 IO 模型(三)

    快过年啦,估计很多朋友已在摸鱼的路上.而我为了兄弟们年后的追逐,却在苦苦寻觅.规划,导致文章更新晚了些,各位猿粉谅解. 上期分享,我们结合新春送祝福的场景,通过一坨坨的代码让 BIO.NIO 编程过程 ...

  3. 【Java技术系列】爱情36技之追美妹的技术

    1. 在古老的非洲大陆上,有个原始人无意中抬头仰望星空,凝视的时间稍微长了一些,超过了外星人设置的阈值,立刻拉响了人类即将产生文明的警报.因为外星人认为,人类已经产生了对宇宙的好奇心,文明的产生,科技 ...

  4. 配置samba和NFS共享服务

                            配置samba和NFS共享服务 1案例1:配置SMB文件夹共享 1.1问题 本例要求在虚拟机server0上发布两个共享文件夹,具体要求如下: 此服务器 ...

  5. Vim中实现PHP函数tags跳转

    编译安装ctags 下载地址:http://ctags.sourceforge.net/ 下载文件:ctags-5.8.tar.gz 解压ctags:tar -zxcf ctags-5.8.tar.g ...

  6. Alpha测试与Beta测试

    粗略说一下Alpha测试与beta测试 1.Alpha测试 α测试是由一个用户在开发环境下进行的测试,也可以是公司内部的用户在模拟实际操作环境下进行的测试.α测试的目的是评价软件产品的功能.局域化.可 ...

  7. Python设计模式(11)-状态模式

    # coding=utf-8 # *状态模式:一个方法的判断逻辑太长,就不容易修改.方法过长,其本质就是,# * 就是本类在不同条件下的状态转移.状态模式,就是将这些判断分开到各个能# * 表示当前状 ...

  8. php.ini配置文件详解(基于5.2.17版本)

    [PHP] ;;;;;;;;;;;;;;;;;;;; About php.ini ;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;; 关于php.ini文件 ;;;;; ...

  9. web.xml配置参数context-param和init-param的区别

    web.xml配置参数context-param和init-param的区别 (2009-04-13 10:29:01) 转载▼ 标签: 杂谈 分类: JavaEE web.xml里面可以定义两种参数 ...

  10. Wpf之HandyControls与MaterialDesign混用之DataGrid

    首先在App.Xaml引入相关资源 <Application.Resources> <ResourceDictionary> <ResourceDictionary.Me ...