ConditionalOnMissingBean 仍然创建一个InternalResourceViewResolver

问题描述 投票:0回答:1

我有一些 Spring Boot(使用 2.7.18)自动配置,它导入此配置,创建一个 InternalResourceViewResolver

@Configuration
@ConditionalOnClass(javax.servlet.jsp.jstl.core.Config.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class ViewResolverConfiguration {

@Bean
public InternalResourceViewResolver internalResourceViewResolver(
        @Value("${spring.mvc.view.prefix:/WEB-INF/jsp/}") String prefix,
        @Value("${spring.mvc.view.suffix:.jsp}") String suffix) {
    final InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    viewResolver.setPrefix(prefix);
    viewResolver.setSuffix(suffix);
    viewResolver.setOrder(InternalResourceViewResolver.HIGHEST_PRECEDENCE);
    return viewResolver;
}

}

我认为这是正常的条件配置。然而,在运行时我有两个InternalResourceViewResolvers,如/actuator/beans所示:

"internalResourceViewResolver": {
                "aliases": [],
                "scope": "singleton",
                "type": "org.springframework.web.servlet.view.InternalResourceViewResolver",
                "resource": "class path resource [com/example/ViewResolverConfiguration.class]",
                "dependencies": [
                    "com.example.ViewResolverConfiguration"
                ]
            },
"defaultViewResolver": {
                "aliases": [],
                "scope": "singleton",
                "type": "org.springframework.web.servlet.view.InternalResourceViewResolver",
                "resource": "class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]",
                "dependencies": [
                    "org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter"
                ]
            },

可以看出,它是来自 WebMvcAutoConfiguration 的,由于某种原因忽略了 @ConditionalOnMissingBean 条件。

    @Bean
    @ConditionalOnMissingBean
    public InternalResourceViewResolver defaultViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix(this.mvcProperties.getView().getPrefix());
        resolver.setSuffix(this.mvcProperties.getView().getSuffix());
        return resolver;
    }

我可以从 /actuator/conditions 看到积极的评价,它确实在该条件下配置了它:

 "WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#defaultViewResolver": [
                {
                    "condition": "OnBeanCondition",
                    "message": "@ConditionalOnMissingBean (types: org.springframework.web.servlet.view.InternalResourceViewResolver; SearchStrategy: all) did not find any beans"
                }
            ],

除了它们基本相同的问题之外,它不应该配置defaultViewResolver,或者有什么我不明白的地方?有人知道如何调查或解决这种情况吗

spring spring-boot spring-mvc
1个回答
0
投票

WebMvcAutoConfiguration 使用

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
以与默认优先级不同的优先级进行自动配置。因此,当评估
@ConditionalOnMissingBean
时,您的 bean 尚未创建,因此它会创建默认的 bean。

要修复此问题,您可以在配置上放置

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
或(按照您的建议)
@AutoConfigureBefore(org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.class)

如果你想查看 bean 的创建顺序,我看到的唯一方法是在这个 方法 (AutoConfigurationSorter) 中放置一个断点,该方法似乎负责排序。

debug: true
配置似乎没有按照创建bean的顺序打印评估报告。

© www.soinside.com 2019 - 2024. All rights reserved.