@Aspect 切不到 Controller 方法,主因是切面未被 Spring 管理或代理未生效;需确保切面加 @Component、在扫描路径内、启用 CGLIB(proxyTargetClass=true),且避免手动 @Bean 注册。

为什么 @Aspect 切不到 Controller 方法?
常见现象是加了 @Aspect 和 @Around,但日志完全不打印——大概率是切面没被 Spring 容器管理,或目标类没走代理。Spring Boot 默认只对 Spring Bean 生效,而 @Controller 类虽是 Bean,但若切面本身没加 @Component 或没被 @EnableAspectJAutoProxy(其实 Boot 默认已启用)扫描到,就失效。
- 确保切面类加了
@Component,且包路径在@SpringBootApplication扫描范围内 - 避免在非 Spring 管理的对象(比如 new 出来的实例、工具类静态方法)上尝试切面
- 如果用了 JDK 动态代理(接口实现类),切面能生效;但若目标类无接口、又没开
proxyTargetClass = true,CGLIB 代理没启用,也会切不到 - 检查是否误用了
@Bean方式手动注册切面——这会导致它脱离 AOP 基础设施,@Aspect注解直接被忽略
@Around 中怎么安全获取请求和响应内容?
不能直接读 HttpServletRequest.getInputStream() 多次,因为流只能消费一次;也不能在 @AfterReturning 里取响应体,因为那时 HttpServletResponse 的输出流可能已关闭或不可读。
- 必须用
ContentCachingRequestWrapper和ContentCachingResponseWrapper包装原始请求/响应,它们会缓存 body 到内存 - 包装操作得在过滤器(
Filter)里提前做,比如自定义OncePerRequestFilter,并在doFilterInternal中完成包装和放行 -
@Around里通过joinPoint.getArgs()拿到的仍是原始 request/response,所以切面前必须确保已被包装过,否则读出来是空 - 注意缓存大小限制:
ContentCachingResponseWrapper默认最多缓存 10KB,超长响应体会被截断,可通过构造函数传入更大值
记录日志时,哪些字段容易漏掉或出错?
看似简单的“记录请求响应”,实际在分布式、异步、文件上传等场景下,很多字段不是直接可拿的。
-
request.getRemoteAddr()在 Nginx 反向代理后通常是127.0.0.1,得从X-Forwarded-For或X-Real-IP头取真实 IP,但要防伪造,需配置信任代理列表 - 请求参数:GET 参数可用
request.getQueryString(),POST 表单用request.getParameterMap(),但 JSON Body 必须靠前面说的ContentCachingRequestWrapper+getContentType()判断后解析 - 响应状态码:不能只看
response.getStatus(),因为有些框架(如 Spring WebFlux)或异常处理器可能在切面执行后才设状态码;稳妥做法是在@AfterReturning或@AfterThrowing中再读一次 - 耗时统计:别用
System.currentTimeMillis()简单相减,要扣掉 AOP 自身开销,更推荐用StopWatch或Instant.now()
性能和线上使用要注意什么?
日志切面一旦开启,每个请求都进一次代理链,开销不小,尤其解析 JSON、格式化大对象、写磁盘日志时。
- 默认关闭全量日志,用配置项(如
logging.aop.enabled=true)控制开关,线上建议只开 WARN+ 错误日志 - 避免在切面里做耗时操作:比如同步调用远程服务、写数据库、序列化大对象;真要落库,改用异步线程池 + 队列缓冲
- 敏感字段(密码、token、身份证号)必须脱敏,不能只靠日志框架的
PatternLayout过滤——因为切面里拿到的是原始字符串,得在记录前手动replaceAll或用正则替换 - 注意日志上下文丢失:如果业务用了
MDC,要在切面开头显式MDC.put("traceId", ...),否则异步线程或子线程里看不到 trace ID
最麻烦的其实是缓存包装器的生命周期管理——它依赖 Filter 的执行顺序,稍一错位(比如在 Spring Security Filter 之后才包装),就可能拿不到登录用户信息;这种链路依赖,比写代码本身还难调试。











