Sunday, August 19, 2018

Spring magic: Dynamically set URI prefix for group of controllers

Overview

Say you have a big Spring or Spring Boot project with a lot of controller, which you want do separate in different groups with different prefixes.

Annotation

Create annotation which is metaannotated with @Controler or @RestController, It will be used as a marker for controller for which we want to change prefix. In our example this annotation is @ApiController

Controller

Annotate your controllers with marker annotation (@ApiContgroller) and put @RequestMapping annotation on path level with path attribute set. This attribute will be changed by the postprocessor.

Postprocessor

Spring uses postprocessors to enhance beans. We use postprocessor which selects beans on existence of our marker annotation (@ApiController); then checks for @RequestMapping annotation and copies all its attributes in a map. Now we have all attributes at disposiotion and can change it as we like. In our our case we change only value and path attributes by appending configured prefix. This prefix is taken from the environment, but other sources can be implemente. The postprocessor is able to process only one marker annotation, but this can be enhanced in future versions.
Two things are very important in postprocessor implementation:

  1. Annotation Data in Class - java.la ng.Class has method called annotationData(),which gives acces to allannotation information. It has to be accessedvia reflection since it is not part of the public API.
  2. Syntesised annotations Spring framework has special way of annotation processing to support some non trivial features as @AliasFor support.We utilise this mechanism to create clone with changed attributes and to substitute annotatios at runtime. 

Project

Source code for example project can be found on GitHub

1 comment:

  1. Thank you for sharing this. Don't we still have any intrinsic alternatives with Spring?

    ReplyDelete

Spring magic: Dynamically set URI prefix for group of controllers

Overview Say you have a big Spring or Spring Boot project with a lot of controller, which you want do separate in different groups with d...