I have a interface driven controller like this:
@ResponseBody
@PreAuthorize("hasAnyRole('ADMIN', 'USER')")
@RequestMapping("/foo")
interface Foo {
@GetMapping("/{id}")
String bar(String id);
}
And an implementation delegating to the actual business logic
@Controller
public class FooImpl implements Foo {
@Override
public String bar(String id) {
return "<actual business logic>";
}
}
I would like to decorate interface Foo
to add additional functionality to the application.
However when I use a jdk proxy and try to start the application with that spring won't register the endpoints anymore. This is because the bean now isn't annotated with @Controller
anymore on the beans type. The annotation is only present on the implementation (and I can't use a @Bean
method because that annotation is only allowed on types) and not the proxy, which is now the type spring web mvc sees. I also can't annotate the decoration and implementation with @Controller because then I will have ambigous mappings since the decoration interface and the implementation will be treated as components where handler mappings need to be created for.
I would also like to keep the controller annotation at the implementation for the actual business logic so that its still obvious where the main focus of the controller is.
So how can I decorate an interface driven controller in spring web mvc keeping the actual implementation and any decorations that shall be applied to it distinct?
I created an additional interface for adding back the @Controller
annotation to the created proxy:
@Controller
public interface AddControllerAnnotations {
}
And I'm passing this interface additionally to the interfaces of the java.lang.reflect.Proxy.newProxyInstance(ClassLoader, Class<?>[], InvocationHandler)
call I'm using to create the proxy instance. This way spring will still consider the decorated instance as a controller.
However this will not scale if there will be more annotations to apply this way.