我正在寻找在运行时注册@RestController的解决方案。我目前正在用((GenericApplicationContext) applicationContext).registerBeanDefinition(name, beanDefinition);
注册bean,但是我不能使用@RestController bean中指定的端点。
解决方案是什么?
我找到了一个解决方案。下面的帖子帮助了我:是否有可能在Spring MVC中动态设置RequestMappings ?
当RequestMappingHandlerMapping被初始化时,它会扫描上下文并创建它需要服务的所有@RequestMappings的映射(可能是出于性能原因)。如果动态注册带有@Controller注释的bean,它们将不会被拾取。要重新触发此扫描,只需要在添加bean之后调用afterPropertiesSet()。"这就是我的解决方案:
@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();
});
更新2022/07/04:非常重要。在测试时,我注意到这个解决方案使现有的路由不再工作。经过一些调试后,我发现这与路由(因为内部使用了MultiValueMap)在刷新期间被添加多次有关。要修复此错误,必须首先在刷新之前从RequestMappingHandlerMapping中删除路由。这可以通过使用requestMappingHandlerMapping.getHandlerMethods().keySet().forEach(requestMappingHandlerMapping::unregisterMapping);
来完成我已经更正了上面的代码片段。