Spring AOP

在 Spring AOP 中:

  • Advice :通知,即切面在某个连接点上要执行的动作,如 @Before、@After、@Around 等。
  • Pointcut:切入点,定义"在哪些方法上应用通知"。
  • Aspect:切面,由 Pointcut + Advice 组成。

Spring AOP 借用了 AspectJ 的表达式语法来定义 Pointcut,但底层实现仍是 Spring 自己的动态代理(JDK Proxy 或 CGLIB),并非 AspectJ 的编译期/加载期织入。

两种定义 Pointcut 的方式

注解方式(主流推荐)
java 复制代码
@Aspect
@Component
public class LoggingAspect {

    @Pointcut("execution(* com.example.service..*.*(..))")
    public void servicePointcut() {}

    @Before("servicePointcut()")
    public void before(JoinPoint jp) {
        System.out.println("方法执行前: " + jp.getSignature());
    }
}

配合 @EnableAspectJAutoProxy 或 <aop:aspectj-autoproxy/> 启用。

XML 配置方式
XML 复制代码
<aop:config>
    <aop:aspect ref="loggingAspect">
        <aop:pointcut id="servicePointcut"
            expression="execution(* com.example.service..*.*(..))"/>
        <aop:before method="before" pointcut-ref="servicePointcut"/>
    </aop:aspect>
</aop:config>

这里 <aop:pointcut> 标签直接在 XML 中定义切入点表达式,expression 属性的写法与注解完全一致。

两者的对比

维度 注解方式 XML 方式
配置位置 与代码内聚 与代码分离
编译期检查 有 无
切点组合复用 支持(可通过方法名引用组合) 不支持命名切点组合
适用场景 现代项目、Spring Boot 遗留系统、需集中管控

官方文档也明确指出,XML 方式的局限之一就是无法像注解那样通过命名切点的组合来构建更复杂的表达式。

AspectJ

AspectJ 的表达式语法是一套用来描述"哪些连接点需要被拦截"的匹配规则。Spring AOP 借用了这套语法,但只支持其中一部分,底层仍是动态代理。

最核心:execution 表达式

execution(修饰符? 返回值 包名.类名.方法名(参数) 异常?)

java 复制代码
// 任意公共方法
execution(public * *(..))

// service 包及其子包下所有类的所有方法
execution(* com.example.service..*.*(..))

// 返回 String,且方法名以 get 开头
execution(String *..get*(..))

通配符:

| 符号 | 含义 |
| * | 匹配任意单个字符(类名、方法名、返回类型等) |
| .. | 在包路径中表示"当前包及所有子包";在参数中表示"任意个数、任意类型的参数" |

+ 匹配指定类及其子类(如 UserService+)

简单记忆:日常开发 90% 的场景用 execution 就够了 ,需要按注解拦截时用 @annotation,按 Bean 名称拦截时用 bean。

相关推荐
秋饼9 分钟前
GPT-Live 全双工语音 API Java 服务端落地实战:事件协议、会话恢复与生产踩坑
java·ai·技术分享·后端开发
SL_staff11 分钟前
为什么企业级自动化不能只靠AI编排?——逻辑引擎在确定性业务场景中的不可替代性
java·开源·产品
路溪非溪37 分钟前
python标准库使用总结
开发语言·python
Pniubi1 小时前
MySQL靠什么实现事务的?事务隔离级别有哪些?
java·数据库·mysql
SomeOtherTime2 小时前
Rust 面向对象介绍(AI回答)
开发语言·python·rust
松仔log2 小时前
Kotlin中级——callbackFlow
java·前端·kotlin
zh_xuan2 小时前
kotlin常见面试题
开发语言·kotlin·面试题
知守观3 小时前
同一个团队两套分包:DDD 四层落地后,domain 层最大的类还是 5885 行
java·后端·领域驱动设计
文丑颜不良啊3 小时前
LeetCode2541~2560题目解析
java·leetcode
瑞雪兆丰年兮3 小时前
JavaWeb-day11-SpringBootWeb案例(文件上传)
java·运维·服务器·javaweb·oss