Programmatically add @Controllers to Spring MVC

Recently I had a requirement to provide a controller as part of a reusable framework that was included in multiple projects. Typically, creating a controller is as simple tagging a class with @Controller and making sure it’s in a package that is scanned, thanks to the annotation scanning introduced in Spring MVC 2.5, however in this case we couldn’t rely solely on package scanning as future versions of controllers would ideally be bundled in the same package. What we ended up need was a way to programmatically add controllers to our application.

The steps to complete it:

  • Create your controller, complete with @Controller and @RequestMapping annotations as necessary. A naive example could be:
  • Have one of your beans or @Configuration classes implement BeanDefinitionRegistryPostProcessor and add your controller as a BeanDefinition like listed below:

 

Notice now that when your app starts up your controller will be scanned and wired up.

This also helped solve an issue where I wanted to add a utility controller in every lane except for production. If you found this useful in any other situation, I’d love to hear about your experiences.

 

Follow up note: On a side note, this little experiment made me realize I didn’t fully understand the Spring container’s contract and the idea that we’re providing “Bean Definitions” rather than instances of beans. The JavaDocs + some googling on “Spring BeanDefinition” gave me some more insights on the matter, especially this short post.