Che*_*hen 6 java aop spring spring-aop spring-boot
我有一个自定义记录器@Aspect,我希望它始终在最后运行,这样无论控制器返回什么响应,它都会被记录到数据库中(所以我@Order(1)在这方面添加了一个)。我还编写了一个错误处理程序,用于@ControllerAdvice处理所有意外异常并返回500自定义响应正文,并且我希望记录器也记录它,因此我@Order(2)在其上添加了一个,但是看起来放置@Order注释并没有安排Spring Aspect 和 Spring ControllerAdvice 之间的命令,那么如何让我的错误处理程序始终在记录器之前运行?(当然,无需将我的错误处理程序转换为另一个 Spring Aspect)
我一直在寻找和调试您的主要问题。我没有找到你的问题的答案@Order,但我会与你分享我的想法(这篇文章的第二部分)
Interceptor吗?它们提供了在进入控制器之前以及执行之后(@ControllerAdvice如果有的话)记录操作的方法。
@Component
public class WebInterceptor extends HandlerInterceptorAdapter {
private Logger logger = LoggerFactory.getLogger(WebInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.error("WebInterceptor prehandle is now logged");
return super.preHandle(request, response, handler);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
logger.error("WebInterceptor after completion is now logged");
super.afterCompletion(request, response, handler, ex);
}
}
Run Code Online (Sandbox Code Playgroud)
要激活此拦截器,您需要创建一个新@Configuration类,实现WebMvcConfigurer:
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Autowired
private WebInterceptor webInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(webInterceptor).addPathPatterns("/user");
}
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个简单的ControllerandControllerAdvice进行测试:
@RestController
public class WebController {
@GetMapping("/user")
public String user() {
throw new IllegalArgumentException("my bad");
}
}
@RestControllerAdvice
@Order(2)
public class WebAdvice {
private Logger logger = LoggerFactory.getLogger(WebAdvice.class);
@ExceptionHandler(RuntimeException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public void handle(RuntimeException e) {
logger.error("ControllerAdvice is now logged");
}
}
Run Code Online (Sandbox Code Playgroud)
结果是:
现在记录 WebAdvice 句柄 现在
记录完成后的 WebInterceptor
如果您需要记录请求,您也可以查看此内容: https: //www.baeldung.com/spring-http-logging
@ControllerAdvice你是对的, an和 a之间没有优先级@Aspect,嗯……
我无法找出原因(还没有),但是当@Aspectin 指向方法时,无论您设置的顺序如何,@Controller切入点都会在 之前执行@ControllerAdvice
@Aspect
@Component
@Order(1)
public class MyAspect {
private Logger logger = LoggerFactory.getLogger(MyAspect.class);
@After("execution(* WebController.user(..))")
public void afterLog() {
logger.error("Aspect is now logged");
}
}
@RestControllerAdvice
@Order(2)
public class WebAdvice {
private Logger logger = LoggerFactory.getLogger(WebAdvice.class);
@ExceptionHandler(RuntimeException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public void handle(RuntimeException e) {
logger.error("ControllerAdvice is now logged");
}
}
Run Code Online (Sandbox Code Playgroud)
如果你的Get http://localhost:8080/user结果将是:
方面现已记录
ControllerAdvice 现已记录
但我发现了一些有趣的事情:如果你设置了一个切入点@After,@ControllerAdvice那么你就会在controllerAdvice之后执行方面:
@Aspect
@Component
@Order(1)
public class MyAspect {
private Logger logger = LoggerFactory.getLogger(MyAspect.class);
@After("execution(* WebAdvice.handle(..)) || execution(* WebController.user(..))")
public void afterLog() {
logger.error("Aspect is now logged");
}
}
Run Code Online (Sandbox Code Playgroud)
执行2次。一份在控制器之后,一份在建议之后。
方面现已记录
ControllerAdvice 现已记录
方面现已记录
也许这可以满足您的需求,但我真的不认为这是一个优雅的解决方案......
还需要解决的事情:
Aspect和 的方法ControllerAdvice无论如何希望它有帮助。如果我找到更好的东西,我会告诉你。
| 归档时间: |
|
| 查看次数: |
6624 次 |
| 最近记录: |