Spring 事物 属性expression=“execution(*service..*.*(..))“

1、execution(): 表达式主体 (必须加上execution)。

2、第一个*号:表示返回值类型,*号表示所有的类型。

3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,cn.smd.service.impl包、子孙包下所有类的方法。

4、第二个*号:表示类名,*号表示所有的类。

5、*(…):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。

书写的注意事项:execution(* cn.smd.service.impl..(…))

<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
    <tx:method name="find" propagation="SUPPORTS"/>
    <tx:method name="add" propagation="REQUIRED"/>
    <tx:method name="update" propagation="REQUIRED"/>
    <tx:method name="del" propagation="REQUIRED"/>
    <tx:method name="*" propagation="REQUIRED"/>
    </tx:attributes>
    </tx:advice>
 <!-- 定义切面 -->
     <aop:config proxy-target-class="true">
     <aop:pointcut id="serviceMethod" expression="execution(* cn.smd.service.impl.*.*(..))"/>
     <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
     </aop:config>
Spring AOP中,AspectJ切点表达式用于定义哪些方法需要被拦截并应用切面逻辑。这两个表达式 `execution(* com.po..*.*service.impl.*.*(..))` 和 `execution(* com.po..*service.impl.*.*(..))` 都试图匹配 `com.po` 包及其子包下的某些类和方法,但它们之间存在细微差别。 ### 表达式分析 #### 1. `execution(* com.po..*.*service.impl.*.*(..))` 这个表达式的含义是: - `execution(...)`:表示匹配任何方法执行。 - `*`:返回类型可以是任意类型。 - `com.po`:指定根包为 `com.po`。 - `..*`:表示匹配 `com.po` 包下的所有子包(包括多层嵌套的子包)。 - `.*service.impl.`:表示在这些子包中查找名称以 `.service.impl.` 结尾的包中的类。 - `*`:表示匹配该包中的所有类。 - `*`:表示匹配该类中的所有方法。 - `(..)`:表示方法参数可以是任意数量和类型的参数。 因此,这个表达式会匹配 `com.po` 包及其所有子包中,位于 `.service.impl.` 包下的所有类的所有方法。例如,它可以匹配 `com.po.user.service.impl.UserService` 类中的所有方法 [^2]。 #### 2. `execution(* com.po..*service.impl.*.*(..))` 这个表达式的含义是: - `execution(...)`:表示匹配任何方法执行。 - `*`:返回类型可以是任意类型。 - `com.po`:指定根包为 `com.po`。 - `..*service.impl.`:表示匹配 `com.po` 包下所有子包中名称以 `*service.impl.` 结尾的包中的类。这里的 `*` 是一个通配符,表示前面的部分可以有任意字符,只要最终形成 `*service.impl.` 的结构即可。 - `*`:表示匹配该包中的所有类。 - `*`:表示匹配该类中的所有方法。 - `(..)`:表示方法参数可以是任意数量和类型的参数。 因此,这个表达式会匹配 `com.po` 包及其所有子包中,名称以 `*service.impl.` 结尾的包中的所有类的所有方法。例如,它可以匹配 `com.po.order.service.impl.OrderService` 类中的所有方法 [^2]。 ### 区别总结 - **第一种表达式** `execution(* com.po..*.*service.impl.*.*(..))` 更加具体,它要求包名必须以 `.service.impl.` 结尾,并且该包必须存在于 `com.po` 包及其子包中。这种写法更倾向于匹配那些明确命名为 `.service.impl.` 的包中的类和方法。 - **第二种表达式** `execution(* com.po..*service.impl.*.*(..))` 更加灵活,它允许包名以任意字符开头,只要最终形成 `*service.impl.` 的结构即可。这意味着它可以匹配更多种类的包名,如 `orderservice.impl`、`userservice.impl` 等等 [^2]。 ### 示例代码 假设有一个项目结构如下: ``` com └── po ├── user │ └── service │ └── impl │ └── UserService.java └── order └── service └── impl └── OrderService.java ``` 对于上述结构,第一个表达式将匹配 `UserService` 和 `OrderService` 类中的所有方法,而第二个表达式同样也会匹配这两个类中的所有方法。但如果存在另一个类 `com.po.payment.service.impl.PaymentService`,那么两个表达式都会匹配到它 [^2]。 ### 相关问题 1. 如何在Spring AOP中定义多个切点? 2. Spring AOP与AspectJ的区别是什么? 3. 如何在Spring AOP中使用注解来定义切点? 4. 如何在Spring Boot中配置AOP? 5. 如何调试Spring AOP中的切点匹配问题?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值