我正在使用Spring Boot 2.1.4.RELEASE。
我有三个gradle模块:应用程序,集成测试和Web。应用程序和集成测试都取决于Web,Web取决于我编写的库。该库具有以下类:
@Configuration
public class WebErrorAutoConfiguration {
@Bean
public CatchAllExceptionHandler catchAllExceptionHandler() {
return new CatchAllExceptionHandler();
}
@ConditionalOnBean(ErrorAttributes.class)
@Bean
public ErrorController errorController(ErrorAttributes errorAttributes) {
return new ErrorController(errorAttributes);
}
}
上述类包含在spring.factories中。
应用程序模块中的@SpringBootApplication可以很好地部署,但是集成测试模块中的@SpringBootApplication不能。错误是:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'errorController' method
public org.springframework.http.ResponseEntity<?> com.sample.package.ErrorController.handleError(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
to { /error}: There is already 'basicErrorController' bean method
我理解原因:我的ErrorController无法实例化,因为已经为/ error定义了处理程序。我不明白为什么在集成测试之外部署应用程序时不会发生这种情况。
Spring如何确定自动配置类的执行顺序?我可以通过将@AutoConfigureBefore(ErrorMvcAutoConfiguration.class)添加到我的WebErrorAutoConfiguration.class来解决此问题,但我想了解两个模块之间的行为差异。我已经查看了在ClassLoader中加载的jar的顺序,但是在这两个实例中,我的库都是在Spring之前加载的。
答案 0 :(得分:0)
spring boot自动配置中的顺序是不同的,因为除非放置@AutoConfigureBefore
,@AutoConfigureAfter
等注释,否则它们无法确保顺序。
当您不指定它们时,它很大程度上取决于您的类路径(在OS,env,build-tools等之间可能有所不同),并且spring命令会读取模块列表。在每种环境中,它可能会略有不同,并且如果要确保执行所需的订单,则需要指定订单。
请注意,您的主应用程序中的任何内容(包中带有@SpringBootApplication
的类中的任何内容)都将首先加载,并且提及的支持自动配置模块顺序的注释不会影响这些配置