2

我有一个自定义 Spring BootAutoConfiguration类,我正在其中创建@RequestScop自定义类的 ed bean - Foo。在同一个AutoConfiguration类中,我正在创建一个全局异常处理程序的 bean,它是一个@ControllerAdvice. 所有这些类都打包为 jar,并在我的其他 Spring Boot Web 应用程序中用作依赖项。每当控制器方法中出现异常时,都会在我的全局异常处理程序中调用适当的异常处理程序,除非在 中出现异常时FooBeanCreationException会抛出 a 并且不会调用任何全局异常处理程序。我尝试@Order(Ordered.HIGHEST_PRECEDENCE)按照一些 SO 答案中的建议添加,但没有一个有效。是否可以在全局异常处理程序中处理此类请求范围的 bean 异常 - a @ControllerAdvice?非常感激。

编辑 这是我的AutoConfiguration课。(这是在另一个罐子里)

@Configuration
@ConditionalOnClass({FooContext.class, MyGlobalExceptionHandler.class})
public class AutoConfiguration {

    // This bean is used in a Controller
    @Order
    @RequestScope
    @Bean
    @ConditionalOnMissingBean(FooContext.class)
    public FooContext fooContext() throws IOException {
        // generateFooContext() throws the exception and Spring wraps it with BeanCreationException.
        return FooContextFactory.generateFooContext(); 
    }

    @Bean
    @ConditionalOnMissingBean
    public MyGlobalExceptionHandler globalExceptionHandler(MyErrorHelper errorHelper) {
        return new MyGlobalExceptionHandler (errorHelper);
    }
}

这是MyGlobalExceptionHandler(这是在另一个罐子里)

@ControllerAdvice
@RefreshScope
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyGlobalExceptionHandler {

    // Never invoked 
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> render(Exception ex) {
        log.error("Exception occurred: ", ex);
        return errorHelper.throwErrorException(DEFAULT_ERROR_CODE, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    /// ... 
}
4

1 回答 1

0

我设法通过注册一个来解决它AbstractHandlerExceptionResolver

@Component
public class ResponseExceptionResolver extends AbstractHandlerExceptionResolver {

    @SneakyThrows
    @Override
    protected ModelAndView doResolveException(
            HttpServletRequest request,
            HttpServletResponse response,
            Object handler,
            Exception ex
    ) {
        return handleException(request, response);
    }

    private ModelAndView handleException(
            HttpServletRequest request,
            HttpServletResponse response
    ) {
        response.setHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE);

        ErrorResponse errorResponse = ...
        return new ModelAndView(new MappingJackson2JsonView(), this.getErrorResponse(errorResponse));
    }

    private Map<String, String> getErrorResponse(ErrorResponse errorResponse) {
        return new ObjectMapper().convertValue(errorResponse, new TypeReference<Map<String, String>>() {
        });
    }
}
于 2020-04-28T11:39:23.253 回答