简体   繁体   English

在运行时注册 spring @RestController

[英]Register spring @RestController at runtime

i am searching a solution to register an @RestController at runtime.我正在寻找在运行时注册@RestController 的解决方案。 I am currently registering the bean with ((GenericApplicationContext) applicationContext).registerBeanDefinition(name, beanDefinition);我目前正在使用((GenericApplicationContext) applicationContext).registerBeanDefinition(name, beanDefinition);注册 bean , but I can't use the endpoint specified in the @RestController bean. ,但我不能使用@RestController bean 中指定的端点。

What's the solution?解决方案是什么?

I found a solution.我找到了解决方案。 The following post helped me: Is it possible to dynamically set RequestMappings in Spring MVC?以下帖子帮助了我: Is it possible to dynamic set RequestMappings in Spring MVC?

Quote: "When RequestMappingHandlerMapping is initialized, it scans the context and creates a map of all @RequestMappings 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."引用:“初始化 RequestMappingHandlerMapping 时,它会扫描上下文并创建它需要服务的所有 @RequestMappings 的 map(可能是出于性能原因)。如果您动态注册使用 @Controller 注释的 bean,它们将不会被拾取。要重新触发此扫描,您只需在添加 bean 后调用 afterPropertiesSet()。”

So that's my solution:所以这就是我的解决方案:

 @Qualifier("requestMappingHandlerMapping") RequestMappingHandlerMapping mappingHandlerMapping
 BeanDefinition beanDefinition = new AnnotatedGenericBeanDefinition(TestController.class); //noinspection ConstantConditions String name = AnnotationBeanNameGenerator.INSTANCE.generateBeanName(beanDefinition, null); ((GenericApplicationContext) applicationContext).registerBeanDefinition(name, beanDefinition); applicationContext.getBeansOfType(RequestMappingHandlerMapping.class).forEach((name, requestMappingHandlerMapping) -> { requestMappingHandlerMapping.getHandlerMethods().keySet().forEach(requestMappingHandlerMapping::unregisterMapping); requestMappingHandlerMapping.afterPropertiesSet(); });

Update 2022/07/04: Very important. 2022/07/04 更新:非常重要。 When testing, I noticed that this solution makes existing routes no longer work.在测试时,我注意到此解决方案使现有路由不再有效。 After a little debugging I found out that this is related to the fact that the routes (because internally a MultiValueMap is used) are added several times during a refresh.经过一点调试,我发现这与在刷新期间多次添加路由(因为内部使用了 MultiValueMap)这一事实有关。 To fix this error the routes must first be removed from the RequestMappingHandlerMapping before a refresh.要修复此错误,必须先从 RequestMappingHandlerMapping 中删除路由,然后再刷新。 This can be done by using requestMappingHandlerMapping.getHandlerMethods().keySet().forEach(requestMappingHandlerMapping::unregisterMapping);这可以通过使用requestMappingHandlerMapping.getHandlerMethods().keySet().forEach(requestMappingHandlerMapping::unregisterMapping);

I have corrected the code snippet above.我已经更正了上面的代码片段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM