Đây có phải là cách người ta mong đợi Spring MVC sẽ hoạt động không?
Kể từ Spring 4.3.7, đây là cách Spring MVC hoạt động: nó sử dụng các HandlerExceptionResolverphiên bản để xử lý các ngoại lệ do các phương thức xử lý ném ra.
Theo mặc định, cấu hình MVC web đăng ký một HandlerExceptionResolverbean duy nhất , a HandlerExceptionResolverComposite,
đại biểu cho một danh sách khác HandlerExceptionResolvers.
Những trình giải quyết khác là
ExceptionHandlerExceptionResolver
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver
đã đăng ký theo thứ tự đó. Đối với mục đích của câu hỏi này, chúng tôi chỉ quan tâm đến ExceptionHandlerExceptionResolver.
An AbstractHandlerMethodExceptionResolvergiải quyết các ngoại lệ thông qua @ExceptionHandlercác phương thức.
Tại khởi bối cảnh, mùa xuân sẽ tạo ra một ControllerAdviceBeancho mỗi @ControllerAdvicelớp chú thích nó phát hiện. Các ExceptionHandlerExceptionResolversẽ lấy những từ ngữ cảnh, và sắp xếp chúng bằng cách sử dụng AnnotationAwareOrderComparatormà
là một phần mở rộng OrderComparatorhỗ trợ Ordered
giao diện của Spring cũng như @Ordervà @Prioritycác chú thích, với giá trị thứ tự được cung cấp bởi một phiên bản Đã đặt hàng ghi đè giá trị chú thích được xác định tĩnh (nếu có).
Sau đó, nó sẽ đăng ký một ExceptionHandlerMethodResolvercho mỗi ControllerAdviceBeantrường hợp này (ánh xạ @ExceptionHandlercác phương thức có sẵn với các loại ngoại lệ mà chúng có ý định xử lý). Chúng cuối cùng được thêm theo cùng một thứ tự vào a LinkedHashMap(bảo toàn thứ tự lặp lại).
Khi một ngoại lệ xảy ra, hàm ExceptionHandlerExceptionResolversẽ lặp qua những cái này ExceptionHandlerMethodResolvervà sử dụng cái đầu tiên có thể xử lý ngoại lệ.
Vì vậy, vấn đề ở đây là: nếu bạn có một @ControllerAdvicevới @ExceptionHandlerfor Exceptionđược đăng ký trước một @ControllerAdvicelớp khác với một @ExceptionHandlerngoại lệ cụ thể hơn, chẳng hạn như IOException, cái đầu tiên đó sẽ được gọi. Như đã đề cập trước đó, bạn có thể kiểm soát thứ tự đăng ký đó bằng cách @ControllerAdvicetriển khai lớp chú thích của bạn Orderedhoặc chú thích nó bằng @Orderhoặc @Priorityvà đặt cho nó một giá trị thích hợp.
@ExceptionHandlerphương thức trong a@ControllerAdvice, phương thức xử lý lớp cha cụ thể nhất của ngoại lệ đã ném được chọn.