如何在bean上提供@ControllerAdvice条件?

时间:2017-06-29 13:48:47

标签: java spring spring-mvc spring-boot

我正在创建一个框架,我希望在以后的所有项目中重复使用。如果子项目没有定义@ControllerAdvice,我希望我的框架自动初始化异常处理的默认建议。

public class ExHandler implements IAdvice {
    ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ResponseBody
    public ErrorDTO default(xception e) {
        return new ErrorDTO();
    }
}

我尝试如下,但不起作用:

@Configuration
static class MyConfig {
    @ControllerAdvice
    @ConditionalOnMissingBean(IAdvice.class)
    static class AdviceExHandler extends ExHandler {

    }
}

在子项目中:

@ControllerAdvice
public class SubHandler extends ExHandler {
}

结果:它有效。但是:如果子项目没有定义ExHandler,那么bean根本就没有初始化!但为什么呢?

旁注:我试图阻止mutliple ControllerAdvice,因为错误处理取决于异常处理程序内部方法的顺序。因此,我不想通过引入多个类来搞乱订单。

2 个答案:

答案 0 :(得分:5)

您可以使用@ConditionalOnMissingBean(annotation = ControllerAdvice.class)通过ControllerAdvice注释配置缺少bean的条件。

@ControllerAdvice
public abstract class FrameworkAdvice {
...
}

并有条件地配置它:

@Configuration
@ConditionalOnMissingBean(annotation = ControllerAdvice.class)
public class FrameworkAdviceConfig {
    @Bean
    public FrameworkAdvice frameworkAdvice() {
        return new FrameworkAdvice() {
        };
    }
}

如果项目中有另一个控制器建议,则会改为使用它。

@ControllerAdvice
public class CustomAdvice {
...
}

答案 1 :(得分:0)

您可以在不使用包装的情况下使用它。只需在Kotlin中声明@ControllerAdvice带注释的类,如下所示:

@ControllerAdvice
@ConditionalOnMissingBean(annotation = [ControllerAdvice::class])
class ExceptionHandler {

    @ResponseStatus(HttpStatus.EXPECTATION_FAILED)
    @ResponseBody
    @ExceptionHandler
    fun handleProcessingException(e: Exception): ErrorDto {
        return ErrorDto()
    }
}

如果您是初学者,请在spring.factories文件中声明它:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  ru.raiffeisen.ecommerce.controller.ExceptionHandler

仅此而已。如果没有@ControllerAdvice带注释的类,则将从配置中使用该类。