Spring-Integration:确保 IntegrationRequestMappingHandlerMapping 已初始化
Spring-Integration: Ensure that IntegrationRequestMappingHandlerMapping is initialized
IntegrationRequestMappingHandlerMapping
有一个特殊的要求要在 ContextRefreshedEvent
上初始化。引用代码:
@Override
public void afterPropertiesSet() {
// No-op in favor of onApplicationEvent
}
/**
* {@link HttpRequestHandlingEndpointSupport}s may depend on auto-created
* {@code requestChannel}s, so MVC Handlers detection should be postponed
* as late as possible.
* @see RequestMappingHandlerMapping#afterPropertiesSet()
*/
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (!this.initialized.getAndSet(true)) {
super.afterPropertiesSet();
}
}
效果是,当其他 bean 在应用程序启动期间尝试对其求值时,其 mappingRegistry
为空,即使它们以 MAX_VALUE
.[=23 阶段实现 SmartLifeCycle
也是如此=]
在我的例子中,我正在尝试为 Springfox 实现一个 spring 集成插件。它 DocumentationPluginsBootstrapper
需要访问请求映射以记录它们。
在我开始请求其映射之前,如何确定 IntegrationRequestMappingHandlerMapping
已经初始化?监听 ContextRefreshedEvent
是否也是正确的方法,但是 @Order
的值很高?或者您会建议使用不同的事件吗?
更新:AbstractHandlerMapping 已经使用 Order.LOWEST_PRECEDENCE。我想我不能使用上下文刷新事件来保证安全。
ContextRefreshedEvent
真的是应用上下文初始化的最后一步:
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
在那finishRefresh()
被解雇了。
您确实应该考虑 Ordered
和 Order.LOWEST_PRECEDENCE
的 ApplicationListener<ContextRefreshedEvent>
。同时框架注册 IntegrationRequestMappingHandlerMapping
与 order == 0
:
private void registerRequestMappingHandlerMappingIfNecessary(BeanDefinitionRegistry registry) {
if (HttpContextUtils.WEB_MVC_PRESENT &&
!registry.containsBeanDefinition(HttpContextUtils.HANDLER_MAPPING_BEAN_NAME)) {
BeanDefinitionBuilder requestMappingBuilder =
BeanDefinitionBuilder.genericBeanDefinition(IntegrationRequestMappingHandlerMapping.class);
requestMappingBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
requestMappingBuilder.addPropertyValue(IntegrationNamespaceUtils.ORDER, 0);
registry.registerBeanDefinition(HttpContextUtils.HANDLER_MAPPING_BEAN_NAME,
requestMappingBuilder.getBeanDefinition());
}
}
所以,您真的不必在自己的侦听器中处理映射。仅仅因为,感谢 order = 0
IntegrationRequestMappingHandlerMapping
将被初始化。
同样适用于 WebFluxIntegrationRequestMappingHandlerMapping
:
private void registerReactiveRequestMappingHandlerMappingIfNecessary(BeanDefinitionRegistry registry) {
if (HttpContextUtils.WEB_FLUX_PRESENT &&
!registry.containsBeanDefinition(WebFluxContextUtils.HANDLER_MAPPING_BEAN_NAME)) {
BeanDefinitionBuilder requestMappingBuilder =
BeanDefinitionBuilder.genericBeanDefinition(WebFluxIntegrationRequestMappingHandlerMapping.class);
requestMappingBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
requestMappingBuilder.addPropertyValue(IntegrationNamespaceUtils.ORDER, 0);
registry.registerBeanDefinition(WebFluxContextUtils.HANDLER_MAPPING_BEAN_NAME,
requestMappingBuilder.getBeanDefinition());
BeanDefinitionReaderUtils.registerWithGeneratedName(
new RootBeanDefinition(IntegrationHandlerResultHandler.class), registry);
}
}
IntegrationRequestMappingHandlerMapping
有一个特殊的要求要在 ContextRefreshedEvent
上初始化。引用代码:
@Override
public void afterPropertiesSet() {
// No-op in favor of onApplicationEvent
}
/**
* {@link HttpRequestHandlingEndpointSupport}s may depend on auto-created
* {@code requestChannel}s, so MVC Handlers detection should be postponed
* as late as possible.
* @see RequestMappingHandlerMapping#afterPropertiesSet()
*/
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (!this.initialized.getAndSet(true)) {
super.afterPropertiesSet();
}
}
效果是,当其他 bean 在应用程序启动期间尝试对其求值时,其 mappingRegistry
为空,即使它们以 MAX_VALUE
.[=23 阶段实现 SmartLifeCycle
也是如此=]
在我的例子中,我正在尝试为 Springfox 实现一个 spring 集成插件。它 DocumentationPluginsBootstrapper
需要访问请求映射以记录它们。
在我开始请求其映射之前,如何确定 IntegrationRequestMappingHandlerMapping
已经初始化?监听 ContextRefreshedEvent
是否也是正确的方法,但是 @Order
的值很高?或者您会建议使用不同的事件吗?
更新:AbstractHandlerMapping 已经使用 Order.LOWEST_PRECEDENCE。我想我不能使用上下文刷新事件来保证安全。
ContextRefreshedEvent
真的是应用上下文初始化的最后一步:
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
在那finishRefresh()
被解雇了。
您确实应该考虑 Ordered
和 Order.LOWEST_PRECEDENCE
的 ApplicationListener<ContextRefreshedEvent>
。同时框架注册 IntegrationRequestMappingHandlerMapping
与 order == 0
:
private void registerRequestMappingHandlerMappingIfNecessary(BeanDefinitionRegistry registry) {
if (HttpContextUtils.WEB_MVC_PRESENT &&
!registry.containsBeanDefinition(HttpContextUtils.HANDLER_MAPPING_BEAN_NAME)) {
BeanDefinitionBuilder requestMappingBuilder =
BeanDefinitionBuilder.genericBeanDefinition(IntegrationRequestMappingHandlerMapping.class);
requestMappingBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
requestMappingBuilder.addPropertyValue(IntegrationNamespaceUtils.ORDER, 0);
registry.registerBeanDefinition(HttpContextUtils.HANDLER_MAPPING_BEAN_NAME,
requestMappingBuilder.getBeanDefinition());
}
}
所以,您真的不必在自己的侦听器中处理映射。仅仅因为,感谢 order = 0
IntegrationRequestMappingHandlerMapping
将被初始化。
同样适用于 WebFluxIntegrationRequestMappingHandlerMapping
:
private void registerReactiveRequestMappingHandlerMappingIfNecessary(BeanDefinitionRegistry registry) {
if (HttpContextUtils.WEB_FLUX_PRESENT &&
!registry.containsBeanDefinition(WebFluxContextUtils.HANDLER_MAPPING_BEAN_NAME)) {
BeanDefinitionBuilder requestMappingBuilder =
BeanDefinitionBuilder.genericBeanDefinition(WebFluxIntegrationRequestMappingHandlerMapping.class);
requestMappingBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
requestMappingBuilder.addPropertyValue(IntegrationNamespaceUtils.ORDER, 0);
registry.registerBeanDefinition(WebFluxContextUtils.HANDLER_MAPPING_BEAN_NAME,
requestMappingBuilder.getBeanDefinition());
BeanDefinitionReaderUtils.registerWithGeneratedName(
new RootBeanDefinition(IntegrationHandlerResultHandler.class), registry);
}
}