
本文深入解析Spring AOP中两种常见切入点表达式 * *..*Repository.find*(..) 与 * *Repository.find*(..) 的本质区别,重点阐明 *.. 在类型模式中的语义、包匹配范围及实际应用注意事项。
本文深入解析spring aop中两种常见切入点表达式 * *..*repository.find*(..) 与 * *repository.find*(..) 的本质区别,重点阐明 *.. 在类型模式中的语义、包匹配范围及实际应用注意事项。
在Spring AOP基于AspectJ的切入点(Pointcut)表达式中,execution() 是最常用的指示符,其完整语法结构为:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
其中,declaring-type-pattern(声明类型模式)决定了目标类所在的包路径匹配规则——而 *..*Repository 与 *Repository 的差异正源于此。
* *..*Repository.find*(..):匹配任意子包下的Repository类
该表达式中,*..*Repository 的含义是:
-
*:匹配任意类名(以Repository结尾); -
..:匹配零个或多个包层级(即任意深度的子包); - 前导
*+..组合*..表示“从根包(java.lang等系统包除外)开始的任意非默认包路径”;
✅ 实际效果:匹配com.example.repo.UserRepository、org.myapp.dao.ProductRepository、io.github.data.JpaRepository等所有位于显式命名包(如com.*、org.*、io.*)中、类名以Repository结尾的类的find*方法;
❌ 不匹配:位于默认包(default package,即无package声明的类)中的UserRepository。
* *Repository.find*(..):仅匹配默认包下的Repository类
该表达式中,*Repository 缺少包路径分隔符,因此 declaring-type-pattern 被解释为无包前缀的简单类名匹配。根据AspectJ规范:
- 当类型模式中不含
.时(如*Repository),它只匹配默认包(default package) 中的类;
✅ 仅匹配:源文件未声明package,直接定义的class UserRepository { ... };
❌ 不匹配:任何带包声明的类(如package com.example; class UserRepository),即使类名完全符合。
⚠️ 注意:Spring官方强烈建议禁止使用默认包。Java语言规范虽允许,但会导致类加载歧义、AOP失效、测试困难及模块化兼容问题。现代Spring Boot项目默认拒绝启动含默认包的组件。
实际配置示例
@Aspect
@Component
public class RepositoryLoggingAspect {
// ✅ 推荐:覆盖所有标准包结构下的Repository
@Pointcut("execution(* *..*Repository.find*(..))")
public void repositoryFindMethods() {}
// ❌ 危险:几乎无法命中(除非真有类在默认包)
@Pointcut("execution(* *Repository.find*(..))")
public void defaultPackageFindMethods() {}
@Before("repositoryFindMethods()")
public void logFindExecution(JoinPoint jp) {
System.out.println("Executing: " + jp.getSignature());
}
}总结与最佳实践
-
..是包路径通配符,*..= “任意非空包路径”,而非“包括根包”; -
*Repository≠ “所有Repository类”,而是“默认包中的Repository类”——生产环境应彻底规避; - 始终采用
*..*Repository或更精确的包限定(如* com.example.**.*Repository.find*(..))提升可维护性; - 通过
@Pointcut抽取复用表达式,并结合@Around/@Before等通知实现横切逻辑; - 使用IDE的AspectJ支持(如IntelliJ的AspectJ Weaver插件)实时验证Pointcut是否生效。
掌握 *.. 的语义,是编写健壮、可移植Spring AOP配置的关键一步。

















