如何在 Spring Boot 2.1.0 启动器配置中将 spring.main.allow-bean-definition-overriding 设置为 true

新手上路,请多包涵

我维护了一个 spring-boot-starter,它可以自定义在调用未知端点时返回的错误属性。这是通过覆盖 org.springframework.boot.web.servlet.error.ErrorAttributes bean 来完成的。

2.0.6 一切正常,但 2.1.0 默认禁用 bean 覆盖,导致启动器现在失败并显示以下消息。

在类路径资源 [com/mycompany/springboot/starter/config/ErrorsConfig.class] 中定义的名称为“errorAttributes”的无效 bean 定义:无法注册 bean 定义 [根 bean:类 [null];范围=;摘要=假;懒惰初始化=假;自动线模式=3;依赖检查=0;自动接线候选=真;主要=假; factoryBeanName=com.mycompany.springboot.starter.config.ErrorsConfig; factoryMethodName=errorAttributes;初始化方法名=空; destroyMethodName=(推断);在类路径资源 [com/mycompany/springboot/starter/config/ErrorsConfig.class]] 中为 bean ‘errorAttributes’ 定义:已经存在 [Root bean: class [null];范围=;摘要=假;懒惰初始化=假;自动线模式=3;依赖检查=0;自动接线候选=真;主要=假; factoryBeanName=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration; factoryMethodName=errorAttributes;初始化方法名=空; destroyMethodName=(推断);在类路径资源 [org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.class]] 中定义

如文档中所述,将 spring.main.allow-bean-definition-overriding 属性设置为 true 可以解决问题。我的问题是如何 在启动器中 执行此操作(我不希望启动器的用户必须更改他们的 application.properties 文件,以获取特定于我的启动器的内容)?

我尝试使用该文件中定义的属性对我的@Configuration 进行@PropertySource(“classpath:/com/mycompany/starter/application.properties”) 注释,但它不起作用。

我错过了什么?有什么方法可以让我的配置覆盖那个 bean?

这是配置的(简化的)源代码:

 @Configuration
@PropertySource("classpath:/com/mycompany/starter/application.properties")
public class ErrorsConfig {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @Bean
    public ErrorAttributes errorAttributes() {
        return new DefaultErrorAttributes() {
            @SuppressWarnings("unchecked")
            @Override
            public Map<String, Object> getErrorAttributes(WebRequest request, boolean includeStackTrace) {
                Map<String, Object> errorAttributes = super.getErrorAttributes(request, includeStackTrace);
                // CustomeError is a (simplified) bean of the error attributes we should return.
                CustomError err = new CustomError("myErrorCode", (String) errorAttributes.get("error"));
                return OBJECT_MAPPER.convertValue(err, Map.class);
            }
        };
    }
}

我的资源文件 com/mycompany/starter/application.properties 包含

spring.main.allow-bean-definition-overriding=true

原文由 Jean-Marc Astesana 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.3k
1 个回答

Spring Boot 的 ErrorAttributes bean 由 ErrorMvcAutoConfiguration 定义。它用 @ConditionalOnMissingBean 注释,因此如果 ErrorAttributes bean 已经定义,它将后退。由于您的 ErrorsConfig 类定义的 bean 正试图覆盖 Boot 的 ErrorAttributes bean 而不是导致它后退,所以您的 ErrorsConfig 类必须在启动后处理 ErrorMvcAutoConfiguration 类。这意味着您的启动器中存在订购问题。

可以使用 @AutoConfigureBefore@AutoConfigureAfter 来控制处理自动配置类的顺序。假设 ErrorsConfig 本身是在 spring.factories 中注册的自动配置类,您可以通过使用 @AutoConfigureBefore(ErrorMvcAutoConfiguration.class) 注释来解决您的问题。 With this change in place ErrorsConfig will define its ErrorAttributes bean before ErrorMvcAutoConfiguration attempts to do so which will cause the auto-configuration of Boot’s ErrorsAttribute 豆退。

原文由 Andy Wilkinson 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进