Spring @ComponentScan排除/包含过滤器

时间:2018-07-20 10:19:23

标签: java spring spring-mvc annotations

在Spring MVC应用程序中,作为一种好的做法,Web配置应仅使用“前端”组件,例如@Controller@RestController
Root应用程序上下文应拾取所有其他bean。

我已经按照以下方式定义了Web配置(请记住,我不需要@EnableMvc注释,因为它扩展了WebMvcConfigurationSupport

@Configuration
@ComponentScan(
        basePackages = { ... },
        useDefaultFilters = false,
        includeFilters = @Filter({
                Controller.class,
                ControllerAdvice.class}))

和Root配置如下。

@Configuration
@ComponentScan(
        basePackages = { ... },
        excludeFilters = @Filter({
                Controller.class,
                ControllerAdvice.class}))

我定义了两个@RestControllerAdvice类,第一个捕获所有通用的Exception,第二个捕获更具体的ServiceException

抛出ServiceException时,从不调用特定顾问,而是仅选择普通顾问。这两个配置类的基本软件包都相同。

我是否还需要在排除和包含过滤器上指定RestControllerAdvice?还是我想念其他东西?

编辑:

两个@RestControllerAdvice都没有basePackeges或任何特定条件。 而ServiceException实际上是已找到并注册的。

如果我将异常处理程序移至工作处理程序,则调用该异常处理程序。 这就是我的工作方式。如果我将ServiceException处理程序移到一个单独的类中,则不会再调用它。

@RestControllerAdvice
public class GlobalRestControllerAdviser extends ResponseEntityExceptionHandler {

    @Override
    protected ResponseEntity<Object> handleBindException(
            final BindException ex,
            final HttpHeaders headers,
            final HttpStatus status,
            final WebRequest request) {
        return new ResponseEntity<Object>(
                buildPresentableError(ex.getAllErrors().get(0)),
                HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(ServiceException.class)
    protected Response<?> handleServiceException(final ServiceException e) {
        ...
    }

    @ExceptionHandler(Exception.class)
    protected ResponseEntity<Object> handleGenericException(final Exception ex) {
        ...
    }
}

好像最通用的ExceptionHandler覆盖了更具体的那个。

2 个答案:

答案 0 :(得分:3)

几乎在这里,使用FilterType type并分离过滤器。

@Configuration
@ComponentScan(
    basePackages = { ... },
    excludeFilters = {
        @ComponentScan.Filter(type=FilterType.ANNOTATION, value=Controller.class),
        @ComponentScan.Filter(type=FilterType.ANNOTATION, value=ControllerAdvice.class)
    }
)

或者,我建议您创建一个自定义注释(例如@FrontEnd)并将过滤器应用于该注释。

答案 1 :(得分:0)

基本上,@ControllerAdvice个带注释的类是有序的,这意味着如果Spring内部人员发现一个@ExceptionHandler接受抛出的异常,它将使用该异常并停止。

具有多个类时,可以使用@Order设置Bean优先级(例如)。用ServiceException注释包含@Order的类使其生效。

此外,根据此功能请求https://jira.spring.io/browse/SPR-8881,我们可以在一个@Filter批注上指定多个类,而无需将它们分成多个@Filter