0

Ultimately what I want to do is dynamically create RestControllers in my Spring project based on some custom bean types. During post processing (via BeanFactoryPostProcessor), I look for particular bean definitions and programmatically generate RestController bean definition for each one. However, I want to set the base path for each of the RestController using the RequestMapping annotation, but I'm not sure how to do this. The AnnotatedBeanDefinition has introspection mechanisms, but I want to be able to specify the value of the RequestMapping annotation. Is there a way to achieve this?

I'm trying to achieve something similar to what Spring Data REST does for Repository: dynamically create a REST endpoint to expose CRUD operations. However, I have slightly different use case that does not fit Spring Data REST's framework.

I have a template controller that exposes some endpoints:

@RestController
class TemplateController<T> {

    private DataService<T> service;

    TemplateController(DataService<T> service) {
        this.service = service;
    }

    @GetMapping("/data")
    T getData() {}

}

Using the BeanFactoryPostProcessor, I scan for all BeanDefinitions for type DataService. What I'm hoping to do next is to register a BeanDefinition for the TemplateController that refers to the specific DataService. However, I want to be able to set different RequestMappings for each of the dynamically defined TemplateControllers.

@Configuration
class Configuration {

    @Bean
    BeanFactoryPostProcessor postProcess() {
        return beanFactory -> {
            //assume a collection of BeanDefinitions for DataService
            dataServiceDefs.forEach {def -> 
                var controllerDef = defineController(def);
                //then insert RequestMapping here hopefully
                asRegistry(beanFactory).register(deriveName(def), controllerDef);
            }
        }

    }

}

Note: The solution suggested in the proposed duplicated question does not address the issue about programmatically adding annotations, or if that's even possible.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Psycho Punch
  • 6,418
  • 9
  • 53
  • 86
  • Can you please explain some more about the specific way you are currently doing this, are you writing->compiling->loading the classes in question, or is there some sort of an abstraction layer that and you are auto-proxying and introspecting method calls? have you considered using plain old java to do this instead? so many questions... also seems that `AnnotatedBeanDefinition` is designed to only read Metadata for annotations and change behaviour but doesn't look safe for mutation. – SaleemKhair Sep 19 '21 at 00:26
  • Have a dynamic route and internally do a redirect to handle your request (via Filters) ? have a dynamic route in DB and do a static route like /dyn/ read and parse the logic. Then render accordingly ?! – Senthil Sep 19 '21 at 01:09
  • @tgdavies I've seen this answer, but I'm trying to define the mapping pre-initialisation because I'd prefer Spring MVC to do most of the handler mapping for me based on what's defined in the `TemplateController` in my example. – Psycho Punch Sep 19 '21 at 14:17
  • @SaleemKhair Thanks. I've updated the question to provide more information. – Psycho Punch Sep 19 '21 at 14:21
  • About adding annotations answer is No, you cannot add annotations at runtime and expect them to behave as if they were added at compile time, spring caches that metadata, and even if you were able to modify the metadata, its not guaranteed that it will have the intended result. HOWEVER you can add behaviour and register mapping to controller class methods, which makes more sense, check the supposed duplicate question. – SaleemKhair Sep 19 '21 at 20:51

0 Answers0