I'm creating a framework that I'd like to reuse in all of my future projects. If the sub project does not define a @ControllerAdvice
, I want my framework to automatically initialize a default Advice for exception handling.
public class ExHandler implements IAdvice {
ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
public ErrorDTO default(xception e) {
return new ErrorDTO();
}
}
I tried as follows, but does not work:
@Configuration
static class MyConfig {
@ControllerAdvice
@ConditionalOnMissingBean(IAdvice.class)
static class AdviceExHandler extends ExHandler {
}
}
In Sub project:
@ControllerAdvice
public class SubHandler extends ExHandler {
}
Result: It works. BUT: if the subproject does not define the ExHandler
, the bean is not initialized at all! But why?
Sidenote: I'm trying to prevent mutliple ControllerAdvice
because error handling depends on the order of methods inside the exception handler. Thus I don't want to mess the order by introducing multiple classes.
You may use @ConditionalOnMissingBean(annotation = ControllerAdvice.class) to configure condition on missing bean with ControllerAdvice annotation.
@ControllerAdvice
public abstract class FrameworkAdvice {
...
}
And conditionally configure it:
@Configuration
@ConditionalOnMissingBean(annotation = ControllerAdvice.class)
public class FrameworkAdviceConfig {
@Bean
public FrameworkAdvice frameworkAdvice() {
return new FrameworkAdvice() {
};
}
}
And if there is another controller advice in project, it will be used instead.
@ControllerAdvice
public class CustomAdvice {
...
}
You could use it without wrappers. Just declare @ControllerAdvice
annotated class as following in Kotlin:
@ControllerAdvice
@ConditionalOnMissingBean(annotation = [ControllerAdvice::class])
class ExceptionHandler {
@ResponseStatus(HttpStatus.EXPECTATION_FAILED)
@ResponseBody
@ExceptionHandler
fun handleProcessingException(e: Exception): ErrorDto {
return ErrorDto()
}
}
And just declare it in spring.factories
file if you're doing it for starter:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
ru.raiffeisen.ecommerce.controller.ExceptionHandler
That's all. If there is no @ControllerAdvice
annotated classes, then will be used class from configuration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With