SpringAOP中@annotation与execution的深度示例对比分析

 更新时间:2025年08月06日 11:19:39   作者:bemyrunningdog  
Spring AOP中@annotation通过注解标记方法,适合定制化横切逻辑;execution基于方法签名匹配,用于通用功能增强,两者互补,根据需求选择,本文给大家介绍SpringAOP中@annotation与execution的深度示例对比分析,感兴趣的朋友一起看看吧

在 Spring AOP 中,@annotationexecution 是两种常用的切点表达式(Pointcut Expression),用于定义哪些方法需要被切面(Aspect)拦截。它们的设计目的、匹配规则和适用场景有显著区别,以下从核心机制、语法、应用场景和示例进行对比分析:

🔍 ​一、核心概念与机制​

1. ​**@annotation表达式**​

  • 作用​:匹配带有特定注解的方法
  • 原理​:基于方法上的注解标记进行拦截,与方法的签名(类名、方法名等)无关。
  • 适用场景​:
    • 需要为特定功能​(如日志、权限校验)标记方法时。
    • 需通过注解传递元数据(例如 @Permission(role="admin"))。
  • 优点​:灵活性高,与业务逻辑解耦,适合自定义横切关注点。
  • 缺点​:需显式在方法上添加注解,无法批量匹配无注解的方法。

2. ​**execution表达式**​

  • 作用​:通过方法签名​(返回值、包名、类名、方法名、参数类型)匹配方法。
  • 原理​:基于方法的结构特征拦截,无需方法添加额外注解。
  • 适用场景​:
    • 批量拦截特定包/类下的所有方法​(如 com.example.service.*.*(..))。
    • 按命名规范匹配方法(如所有 update* 开头的方法)。
  • 优点​:无需修改代码,适合通用功能(如接口耗时统计)。
  • 缺点​:表达式复杂,对无规则的方法难以精确匹配。

⚙️ ​二、语法详解​

1. ​**@annotation语法**​

@Before("@annotation(com.example.Loggable)")
public void logBefore(JoinPoint joinPoint) {
    // 通知逻辑
}
  • 参数​:注解的全限定类名(如 com.example.Loggable)。
  • 扩展​:可与自定义注解结合,实现动态控制(例如 @Loggable(level="DEBUG"))。

2. ​**execution语法**​

@Around("execution(* com.example.service.*.*(..))")
public Object monitor(ProceedingJoinPoint pjp) throws Throwable {
    // 环绕通知逻辑
}
  • 结构​:execution(修饰符? 返回值 包.类.?方法名(参数) 异常?)
    • *:通配任意元素(如返回值、单层包名)。
    • ..:通配多层包或任意参数(如 com..*.ServiceImpl 匹配 com 下所有子包的 ServiceImpl 类)。
  • 示例​:
    • 匹配 UserService 的所有方法:execution(* com.service.UserService.*(..))
    • 匹配所有 save 开头的方法:execution(* save*(..))

🧩 ​三、典型场景对比​

维度​**@annotation**​​**execution**​
匹配依据方法上的注解标记方法签名(包、类、方法名、参数等)
代码侵入性需在方法上添加注解无侵入,直接匹配方法结构
灵活性高(可通过注解参数定制逻辑)中(依赖方法命名和包结构)
适用案例- 权限校验(@RequireAuth
- 日志分级(@LogLevel("DEBUG")
- 接口耗时统计
- 全局事务管理
- 包级别异常处理
复杂匹配能力弱(仅依赖注解是否存在)强(支持通配符、逻辑运算符组合)

💻 ​四、代码示例​

1. ​**@annotation实现自定义日志**​

// 自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Loggable {}
// 切面类
@Aspect
@Component
public class LogAspect {
    @Before("@annotation(com.example.Loggable)")
    public void logMethodCall(JoinPoint jp) {
        System.out.println("Log: " + jp.getSignature().getName());
    }
}
// 业务方法使用
@Service
public class UserService {
    @Loggable
    public void createUser() { ... }
}

2. ​**execution实现方法耗时统计**​

@Aspect
@Component
public class TimeAspect {
    @Around("execution(* com.example.service.*.*(..))")
    public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = pjp.proceed();
        long duration = System.currentTimeMillis() - start;
        System.out.println(pjp.getSignature() + " executed in " + duration + "ms");
        return result;
    }
}

✅ ​五、如何选择?​​

  • ​优先 @annotation​:
    当需要精细控制且逻辑与业务无关时(如权限、审计日志),通过注解实现解耦。
  • ​优先 execution​:
    需批量拦截​(如全局性能监控)或无法修改源码时,通过方法签名覆盖。
  • ​混合使用​:
    复杂场景可组合表达式,例如:
@Before("@annotation(com.example.Auth) && execution(* com.service.*.*(..))")

💎 ​总结​

  • ​**@annotation​:注解驱动,精准标记方法,适合高定制化横切逻辑**。
  • ​**execution​:结构驱动,无侵入匹配,适合通用功能增强**。
    两者本质是互补工具,实际开发中需根据侵入性容忍度匹配精度维护成本综合选择。

到此这篇关于SpringAOP中@annotation与execution的深度对比的文章就介绍到这了,更多相关springaop @annotation与execution内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java httpClient介绍以及使用示例

    Java httpClient介绍以及使用示例

    这篇文章主要介绍了Java httpClient介绍以及使用示例,帮助大家更好的利用Java实现HTTP请求,感兴趣的朋友可以了解下
    2020-10-10
  • Java JDK 1.8 lambda的用法详解

    Java JDK 1.8 lambda的用法详解

    这篇文章主要介绍了Java JDK 1.8 lambda的用法详解,文中给大家提到了jdk 1.8 Lambda 表达式 遍历数组的方法,需要的朋友可以参考下
    2019-09-09
  • Java同学找工作最懵圈的问题:到底啥是分布式系统开发经验?(推荐)

    Java同学找工作最懵圈的问题:到底啥是分布式系统开发经验?(推荐)

    这篇文章主要介绍了分布式系统开发经验,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • JDK动态代理过程原理及手写实现详解

    JDK动态代理过程原理及手写实现详解

    这篇文章主要为大家介绍了JDK动态代理过程原理及手写实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • java实现左旋转字符串

    java实现左旋转字符串

    这篇文章主要为大家详细介绍了java实现左旋转字符串,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • Java 超详细讲解Spring MVC异常处理机制

    Java 超详细讲解Spring MVC异常处理机制

    Spring MVC中提供了一个通用的异常处理机制,它提供了一个成熟、简洁并且清晰的异常处理方案。当使用Spring MVC开发Web应用时,利用这套现成的机制进行异常处理也更加自然并且高效
    2022-04-04
  • swagger注解@ApiModelProperty失效情况的解决

    swagger注解@ApiModelProperty失效情况的解决

    这篇文章主要介绍了swagger注解@ApiModelProperty失效情况的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Java 和 JavaScript 真正通用的Base64编码详解

    Java 和 JavaScript 真正通用的Base64编码详解

    这篇文章主要介绍了Java 和 JavaScript 真正通用的Base64编码详解的相关资料,附有Java和Javascript 的Base64编码,需要的朋友可以参考下
    2016-11-11
  • 修改maven本地仓库路径的方法

    修改maven本地仓库路径的方法

    本篇文章主要介绍了修改maven本地仓库路径的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • Spring事件监听源码解析流程分析

    Spring事件监听源码解析流程分析

    spring事件监听机制离不开容器IOC特性提供的支持,比如容器会自动创建事件发布器,自动识别用户注册的监听器并进行管理,在特定的事件发布后会找到对应的事件监听器并对其监听方法进行回调,这篇文章主要介绍了Spring事件监听源码解析,需要的朋友可以参考下
    2023-08-08

最新评论