详解Spring 框架中切入点 pointcut 表达式的常用写法

自从使用 AspectJ 风格切面配置,使得 spring 的切面配置大大简化,但是 AspectJ 是另外一个开源项目,其规则表达式的语法也稍稍有些怪异。

下面给出一些常见示例的写法,例如,下面是一个对 Service 包上所有方法的切面配置:

<aop:config>
  <aop:pointcut id="serviceOperation" expression="execution(* *..service*..*(..))"/>
  <aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice"/>
</aop:config>

表达式所处位置如上pointcut的位置。配置这个是为了更好控制切面上的事务,下面是一个事物配置的简单例子:

<tx:advice id="txAdvice" transaction-manager="transactionManager">
   <tx:attributes>
      <tx:method name="delete*" rollback-for="Exception"/>
      <tx:method name="save*" rollback-for="Exception"/>
      <tx:method name="update*" rollback-for="Exception"/>
      <tx:method name="*" read-only="true" rollback-for="Exception"/>
    </tx:attributes>
</tx:advice>

通过切面、通知的配置,就为所有的以delete、save和update开头的方法添加上了一致性事务,对其他方法添加上了只读事务。

这个还不够细,如果要写更为详细的控制,就需要研究 AspectJ 切点配置的语法了,其实研究这些标准,还不如拿几个例子看看,解决实际问题就行了。就像写正则表达式一样,标准明摆着,要写好却不容易,从例子着手就能快速上手和领悟。

以下文档来自 Spring 中文开发指南 2.5 文档,由满江红开源组织翻译:

Spring AOP 用户可能会经常使用 execution 切入点指示符。执行表达式的格式如下:

execution(modifiers-pattern?
ret-type-pattern declaring-type-pattern?
name-pattern(param-pattern)throws-pattern?)

除了返回类型模式(上面代码片断中的 ret-type-pattern),名字模式和参数模式以外, 所有的部分都是可选的。返回类型模式决定了方法的返回类型必须依次匹配一个连接点。 你会使用的最频繁的返回类型模式是*,它代表了匹配任意的返回类型。 一个全限定的类型名将只会匹配返回给定类型的方法。名字模式匹配的是方法名。你可以使用*通配符作为所有或者部分命名模式。 参数模式稍微有点复杂,()匹配了一个不接受任何参数的方法, 而(..)则匹配了一个接受任意数量参数的方法(零或者更多)。模式(*)匹配了一个接受一个任何类型的参数的方法。 模式(*,String)匹配了一个接受两个参数的方法,第一个可以是任意类型, 第二个则必须是 String 类型。更多的信息请参阅 AspectJ 编程指南中 语言语义的部分。下面给出一些通用切入点表达式的例子。

任意公共方法的执行:

execution(public * *(..))

任何一个名字以 set 开始的方法的执行:

execution(* set*(..))

AccountService 接口定义的任意方法的执行:

execution(* com.xyz.service.AccountService.*(..))

在 service 包中定义的任意方法的执行:

execution(* com.xyz.service.*.*(..))

在 service 包或其子包中定义的任意方法的执行:

execution(* com.xyz.service..*.*(..))

在 service 包中的任意连接点(在 Spring AOP 中只是方法执行):

within(com.xyz.service.*)

在 service 包或其子包中的任意连接点(在 Spring AOP 中只是方法执行):

within(com.xyz.service..*)

实现 AccountService 接口的代理对象的任意连接点 (在 Spring AOP 中只是方法执行):

this(com.xyz.service.AccountService)

实现 AccountService 接口的目标对象的任意连接点 (在 Spring AOP 中只是方法执行):

target(com.xyz.service.AccountService)

任何一个只接受一个参数,并且运行时所传入的参数是 Serializable 接口的连接点(在 Spring AOP 中只是方法执行):

args(java.io.Serializable)

请注意在例子中给出的切入点不同于execution(* *(Java.io.Serializable)),args 版本只有在动态运行时候传入参数是 Serializable 时才匹配,而 execution 版本在方法签名中声明只有一个 Serializable 类型的参数时候匹配。

目标对象中有一个 @Transactional 注解的任意连接点 (在 Spring AOP 中只是方法执行):

@target(org.springframework.transaction.annotation.Transactional)

任何一个目标对象声明的类型有一个 @Transactional 注解的连接点 (在 Spring AOP 中只是方法执行):

@within(org.springframework.transaction.annotation.Transactional)

任何一个执行的方法有一个 @Transactional 注解的连接点 (在 Spring AOP 中只是方法执行):

@annotation(org.springframework.transaction.annotation.Transactional)

任何一个只接受一个参数,并且运行时所传入的参数类型具有 @Classified 注解的连接点(在 Spring AOP 中只是方法执行):

@args(com.xyz.security.Classified)

任何一个在名为 tradeService 的 Spring bean 之上的连接点 (在 Spring AOP 中只是方法执行):

bean(tradeService)

任何一个在名字匹配通配符表达式*Service的 Spring bean 之上的连接点 (在 Spring AOP 中只是方法执行):

bean(*Service)

其中,thistagartargs@target @with@annotation@args在绑定表单中更加常用。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • struts2+spring+hibernate分页代码[比较多]第1/7页

    dao层接口: Java代码 复制代码 代码如下: package com.last999.im.news.dao; import java.util.*; import com.last999.im.news.entity.KindEntity; import com.last999.im.news.web.PageTool; public interface KindEntityDao{ public KindEntity get(String uuid); public void save

  • Spring MVC 框架搭建配置方法及详解

    现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过要想灵活运用Spring MVC来应对大多数的Web开发,就必须要掌握它的配置及原理. 一.Spring MVC环境搭建:(Spring 2.5.6 + Hibernate 3.2.0) 1. jar包引入 Spring 2.5.6:spring.jar.spring-webmvc.jar.comm

  • Spring中的事务管理实例详解

    本文实例讲述了Spring中的事务管理.分享给大家供大家参考.具体分析如下: 事务简介: 事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性 事务就是一系列的动作,它们被当作一个单独的工作单元.这些动作要么全部完成,要么全部不起作用 事务的四个关键属性(ACID) ① 原子性(atomicity):事务室一个原子操作,有一系列动作组成.事务的原子性确保动作要么全部完成,要么完全不起作用 ② 一致性(consistency):一旦所有事务动作完成,事务就被提交.数据和资源就

  • 详解Java的Spring框架中的注解的用法

    1. 使用Spring注解来注入属性 1.1. 使用注解以前我们是怎样注入属性的 类的实现: class UserManagerImpl implements UserManager { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } ... } 配置文件: <bean id="userManagerImpl" class="com.

  • Spring实现文件上传(示例代码)

    在实际开发中,经常遇到要实现文件上传到服务器端的功能.Spring可以继承commons-fileupload插件来实现文件上传的功能.分为前端JSP编写和后台Controller的编写. 前期准备工作,首先要引入commons-fileupload这个jar包,pom.xml中的配置如下: 复制代码 代码如下: <!-- 实现文件上传,spring集成了这个功能 --><dependency> <groupId>commons-fileupload</group

  • SpringMVC文件上传 多文件上传实例

    必须明确告诉DispatcherServlet如何处理MultipartRequest.SpringMVC中提供了文件上传使用方式如下配置xxx-servlet.xml,添加如下代码: 复制代码 代码如下: <bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">          <!-- 设置

  • Spring事务管理只对出现运行期异常进行回滚

    一.结论 Spring的事务管理默认只对出现运行期异常(java.lang.RuntimeException及其子类)进行回滚. 如果一个方法抛出Exception或者Checked异常,Spring事务管理默认不进行回滚. 关于异常的分类一下详细介绍: 1.基本概念 看java的异常结构图  Throwable是所有异常的根,java.lang.Throwable Error是错误,java.lang.Error Exception是异常,java.lang.Exception 2.Excep

  • springboot与mybatis整合实例详解(完美融合)

    简介 从 Spring Boot 项目名称中的 Boot 可以看出来,Spring Boot 的作用在于创建和启动新的基于 Spring 框架的项目.它的目的是帮助开发人员很容易的创建出独立运行和产品级别的基于 Spring 框架的应用.Spring Boot 会选择最适合的 Spring 子项目和第三方开源库进行整合.大部分 Spring Boot 应用只需要非常少的配置就可以快速运行起来. Spring Boot 包含的特性如下: 创建可以独立运行的 Spring 应用. 直接嵌入 Tomc

  • SpringMVC+MyBatis声明式事务管理

    采用的基本搭建环境:SpringMVC.MyBatis.MySQL.tomcat Spring事务管理分解了传统的全局事务管理和本地事务管理的劣势,使得在任何环境中都可以使用统一的事务管理模型,你可以写一次代码,然后在不同的环境从你的代码里面配置不同的事务管理策略,Spring提供两种事务管理策略:一种是声明式事务管理策略,另一种是编程式事务管理策略,这里主要介绍声明式事务管理策略 由于采用的是SpringMVC. MyBatis,故统一采用了标注来声明Service.Controller 由于

  • Spring常用注解汇总

    本文汇总了Spring的常用注解,以方便大家查询和使用,具体如下: 使用注解之前要开启自动扫描功能 其中base-package为需要扫描的包(含子包). <context:component-scan base-package="cn.test"/> @Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean. @Scope注解 作用域 @Lazy(true) 表示延迟初始化 @Service用于

随机推荐