当前位置: 代码网 > it编程>编程语言>Java > Spring AOP 中@annotation的两种写法使用

Spring AOP 中@annotation的两种写法使用

2026年02月11日 Java 我要评论
在 spring aop 的开发中,我们经常看到这样的切面写法:@before("@annotation(com.example.annotation.paylog)")public void bef

在 spring aop 的开发中,我们经常看到这样的切面写法:

@before("@annotation(com.example.annotation.paylog)")
public void beforeannotation() {
    system.out.println("通过 @annotation 拦截带 @paylog 注解的方法");
}

或者这样:

@before("@annotation(paylog)")
public void beforeannotation(paylog paylog) {
    system.out.println("检测到支付操作:" + paylog.value());
}

看起来很相似,但又不太一样 🤔
到底有什么区别?为什么都能生效?
这篇文章帮你彻底搞清楚!

一、什么是 @annotation

在 aop(aspect-oriented programming,面向切面编程)中,
我们通过切点表达式定义要拦截的方法。

其中,@annotation(...) 是一种非常常见的表达式,用来匹配:

“所有带有指定注解的方法”。

举个例子

假设我们定义了一个自定义注解 @paylog

@target(elementtype.method)
@retention(retentionpolicy.runtime)
public @interface paylog {
    string value() default "默认支付";
}

二、写法一:只拦截方法,不读取注解内容

@aspect
@component
public class payaspect {

    @before("@annotation(com.example.annotation.paylog)")
    public void beforeannotation() {
        system.out.println("通过 @annotation 拦截带 @paylog 注解的方法");
    }
}

这段切面表示:

“在执行任何带有 @paylog 注解的方法之前,先执行我这个方法。”

示例:

@service
public class orderservice {

    @paylog
    public void pay() {
        system.out.println("执行支付逻辑...");
    }
}

输出:

通过 @annotation 拦截带 @paylog 注解的方法
执行支付逻辑...

🧩 解释:

  • @annotation(com.example.annotation.paylog) 表示拦截所有被该注解标记的方法;
  • beforeannotation() 方法执行时,并不会接收到注解对象;
  • 这种写法适合只想拦截,不需要读取注解里的内容。

三、写法二:拦截 + 获取注解对象

@aspect
@component
public class payaspect {

    @before("@annotation(paylog)")
    public void beforeannotation(paylog paylog) {
        system.out.println("检测到支付操作:" + paylog.value());
    }
}

这段代码看起来只多了一个参数 paylog
其实功能更强大——它可以直接获取目标方法上的注解实例。

示例

@service
public class orderservice {

    @paylog("微信支付")
    public void paywx() {
        system.out.println("执行微信支付逻辑...");
    }

    @paylog("支付宝支付")
    public void payali() {
        system.out.println("执行支付宝支付逻辑...");
    }
}

输出结果:

检测到支付操作:微信支付
执行微信支付逻辑...
检测到支付操作:支付宝支付
执行支付宝支付逻辑...

🧠 解释:

  • @annotation(paylog) 告诉 aop:
    拦截时把目标方法上的 @paylog 实例赋值给 paylog 参数;
  • 于是我们可以直接通过 paylog.value() 获取注解中的值。

四、两种写法的对比总结

对比项写法一写法二
表达式@annotation(com.example.annotation.paylog)@annotation(paylog)
方法参数有(注解类型参数)
是否能读取注解内容❌ 否✅ 可以
主要用途只做拦截、执行前后逻辑需要读取注解参数(如描述、类型等)
示例应用简单记录日志根据注解参数执行不同逻辑

五、完整运行示例

1、自定义注解

package com.example.annotation;

import java.lang.annotation.*;

@target(elementtype.method)
@retention(retentionpolicy.runtime)
public @interface paylog {
    string value() default "默认支付类型";
}

2、aop 切面类

package com.example.aspect;

import com.example.annotation.paylog;
import org.aspectj.lang.annotation.aspect;
import org.aspectj.lang.annotation.before;
import org.springframework.stereotype.component;

@aspect
@component
public class payaspect {

    // 写法一:只拦截
    @before("@annotation(com.example.annotation.paylog)")
    public void onlyintercept() {
        system.out.println("拦截到带 @paylog 注解的方法");
    }

    // 写法二:拦截 + 获取注解
    @before("@annotation(paylog)")
    public void beforewithannotation(paylog paylog) {
        system.out.println("检测到支付操作:" + paylog.value());
    }
}

3、被拦截的业务类

package com.example.service;

import com.example.annotation.paylog;
import org.springframework.stereotype.service;

@service
public class orderservice {

    @paylog("微信支付")
    public void paywx() {
        system.out.println("执行微信支付逻辑...");
    }

    @paylog("支付宝支付")
    public void payali() {
        system.out.println("执行支付宝支付逻辑...");
    }
}

4、输出结果

拦截到带 @paylog 注解的方法
检测到支付操作:微信支付
执行微信支付逻辑...

拦截到带 @paylog 注解的方法
检测到支付操作:支付宝支付
执行支付宝支付逻辑...

六、总结

@annotation 有两种写法:

  • @annotation(注解类路径):只拦截,不读参数;
  • @annotation(变量名) + 方法参数:拦截并获取注解对象。

两者都对,只是用途不同

场景推荐写法
只想拦截注解方法,不关心内容@annotation(com.xxx.paylog)
需要读取注解参数(如 type、desc)@annotation(paylog) + paylog paylog
想统一记录操作日志推荐带参数写法,灵活性更强

到此这篇关于spring aop 中@annotation的两种写法使用的文章就介绍到这了,更多相关spring aop @annotation内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com