I know this is really old but I figured I toss this in in case anyone else has the same rough experience I did trying to make this work. I ended up taking advantage of two features of Spring: the ability to dynamically register beans after the context is started and the afterPropertiesSet()
method on the RequestMappingHandlerMapping
object.
When RequestMappingHandlerMapping
is initialized, it scans the context and creates a map of all @RequestMapping
s that it needs to serve (presumably for performance reasons). If you dynamically register beans annotated with @Controller
, they will not be picked them up. To retrigger this scan, you just need to call afterPropertiesSet()
after you've added your beans.
In my particular use case, I instantiated the new @Controller
objects in a separate Spring context and needed to wire them into my WebMvc context. The particulars of how the objects don't matter for this though, all you need is an object reference:
//register all @Controller beans from separateContext into webappContext
separateContext.getBeansWithAnnotation(Controller.class)
.forEach((k, v) -> webappContext.getBeanFactory().registerSingleton(k, v));
//find all RequestMappingHandlerMappings in webappContext and refresh them
webappContext.getBeansOfType(RequestMappingHandlerMapping.class)
.forEach((k, v) -> v.afterPropertiesSet());
For example, you could also do this:
//class annotated with @Controller
MyController controller = new MyController
//register new controller object
webappContext.getBeanFactory().registerSingleton("myController", controller);
//find all RequestMappingHandlerMappings in webappContext and refresh them
webappContext.getBeansOfType(RequestMappingHandlerMapping.class)
.forEach((k, v) -> v.afterPropertiesSet());