我有一些 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,或者有什么我不明白的地方?有人知道如何调查或解决这种情况吗
@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的顺序打印评估报告。