@Before 在目标方法执行前运行,用于日志、校验等;@After 在方法执行后运行(无论是否异常),用于清理资源;二者均需配合 @Aspect 和 @Pointcut 使用,不可直接标注业务方法。

Spring 中的 @Before 和 @After 是 AOP(面向切面编程)的常用通知类型,用于在目标方法执行前或执行后插入通用逻辑,比如日志、权限校验、资源清理等。它们需配合切面(@Aspect)和切入点(@Pointcut)使用,不能直接加在业务方法上。
配置前提:启用 AOP 支持
确保项目已引入 Spring AOP 依赖(如 spring-boot-starter-aop),且 Spring Boot 项目默认自动配置;传统 Spring XML 配置需添加 <aspectj-autoproxy></aspectj-autoproxy>。
定义切面类并声明通知
创建一个被 @Aspect 和 @Component 标记的类,编写 @Before 和 @After 方法:
-
@Before在目标方法调用前执行,但不拦截异常或返回值;若需访问方法参数,可用JoinPoint获取 -
@After在目标方法执行后执行(无论是否抛异常),无法获取返回值;适合做清理类操作 - 两者都必须指定切入点表达式(如
"execution(* com.example.service..*.*(..))")
典型用法示例
以下是一个记录方法执行时间和统一清理资源的简单切面:
@Aspect
@Component
public class LoggingAspect {
<pre class="brush:php;toolbar:false;">@Pointcut("execution(* com.example.service.UserService.*(..))")
public void userServiceMethods() {}
@Before("userServiceMethods()")
public void logBefore(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().toShortString();
System.out.println("[Before] 开始执行:" + methodName);
}
@After("userServiceMethods()")
public void logAfter(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().toShortString();
System.out.println("[After] 执行完成:" + methodName);
}}
注意:@After 不等价于 finally 块(它不捕获异常),如需异常后执行,请用 @AfterThrowing;如需成功后执行并获取返回值,请用 @AfterReturning。
常见注意事项
- 切面类必须由 Spring 容器管理(加
@Component或显式注册为 Bean) - 切入点表达式要准确匹配目标方法,包路径、修饰符、参数列表需一致
-
@Before和@After的执行顺序受切面优先级影响,可通过@Order控制 - 它们无法修改目标方法的参数或返回值——这类需求应使用
@Around
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











