Reputation: 195
I am trying a write RestControllerAdvice which is part of a common library that I want to be available on a present of a certain property. As per our common library, we define all bean via configuration but not with annotation so that we can import that configuration class on demand instead of creating those beans always. But I am finding it difficult to mention that bean is actually of type RestControllerAdvice type in a spring configuration class.
Below is my RestControllerAdvice. I remove the @RestControllerAdvice
from this ExceptionHandler otherwise this bean will be created anyways and in my configuration class I added @AliasFor(annotation = RestControllerAdvice.class)
but I am not sure if its a correct way and it didn't work either.
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ExceptionHandler {
@ExceptionHandler(CustomException.class)
@ResponseBody
public ResponseEntity<Void> handleMyException(CustomException e) {
return new ResponseEntity(new UnauthorizedResponse().withMessage(e.getMessage()).withStatus(HttpStatus.UNAUTHORIZED.value()), null, HttpStatus.UNAUTHORIZED);
}
}
@Configuration
public class ServiceCommonConfiguration {
@Bean
@AliasFor(annotation = RestControllerAdvice.class)
@ConditionalOnProperty(name = PROPERTY, havingValue = "enable")
public ExceptionHandler serviceCommonExceptionHandler() {
return new ExceptionHandler();
}
}
Upvotes: 3
Views: 3127
Reputation: 638
Please try this:
@Configuration
public class ServiceCommonConfiguration {
@RestControllerAdvice
@ConditionalOnProperty(name = PROPERTY, havingValue = "enable")
private class SpecificExceptionHandler extends ExceptionHandler {
// Extends 'ExceptionHandler' class in your question.
}
}
Spring can create beans from inner classes and as far as I tested, instances of even private
and non-static classes are successfully created.
Of course, you can use this configuration class by using @Import
like below.
@Configuration
@Import(ServiceCommonConfiguration.class)
public class SomeUserOfLibraryConfiguration {....
When you neither import the configuration class nor make Spring component-scan the package of the class, the bean of the exception handler is not created.
NOTE
@RestControllerAdvice
/@ControllerAdvice
annotations only on the class level and can't use them on the method level. So you need to declare a class and annotate the class with one of them.@AliasFor
annotation, as its javadoc says, 'is used to declare aliases for annotation attributes'(@RestControllerAdvice
's source code is a good example). So, I think @AliasFor(annotation = RestControllerAdvice.class)
does nothing in your source code above.See Also
Spring Framework Documentation Core Technologies - 1.3.2. Instantiating Beans
Upvotes: 2