一尘不染

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

spring-boot

我维护了一个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定义[root
bean:class [null]; scope =; abstract = false; lazyInit = false; autowireMode
= 3; dependencyCheck = 0; autowireCandidate = true; primary = false;
factoryBeanName = com.mycompany.springboot.starter.config.ErrorsConfig;
factoryMethodName = errorAttributes; initMethodName = null;
destroyMethodName =(推断); 在类路径资源[com / mycompany / springboot / starter /
config / ErrorsConfig.class]中为bean’errorAttributes’定义:已经存在[root bean:class
[null]; scope =; abstract = false; lazyInit = false; autowireMode = 3;
dependencyCheck = 0; autowireCandidate = true; primary = false;
factoryBeanName =
org.springframework.boot.autoconfigure.web.servlet。error.ErrorMvcAutoConfiguration;
factoryMethodName = errorAttributes; initMethodName = null;
destroyMethodName =(推断); 在类路径资源[org / springframework / boot / autoconfigure
/ web / servlet / error / ErrorMvcAutoConfiguration.class]中定义

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

我尝试将@PropertySource(“
classpath:/com/mycompany/starter/application.properties”)批注添加到我的@Configuration中,并在该文件中定义了该属性,但它不起作用。

我想念什么?有什么办法可以让我的配置覆盖该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


阅读 10161

收藏
2020-05-30

共1个答案

一尘不染

Spring
Boot的ErrorAttributesbean由定义ErrorMvcAutoConfiguration。带有注释,@ConditionalOnMissingBean因此如果ErrorAttributes已经定义了bean
,它将取消。由于ErrorsConfig类定义的Bean
试图覆盖Boot的ErrorAttributesbean而不是使其退出,因此ErrorsConfig必须在Boot的ErrorMvcAutoConfiguration类之后对您的类进行处理。这意味着您的起动器有订购问题。

可以使用@AutoConfigureBefore和来控制自动配置类的处理顺序@AutoConfigureAfter。假设ErrorsConfig本身就是在其中注册的自动配置类spring.factories,则可以通过使用注释解决问题@AutoConfigureBefore(ErrorMvcAutoConfiguration.class)。进行此更改后,ErrorsConfigErrorAttributesErrorMvcAutoConfiguration尝试进行定义之前定义其bean,这将导致Boot
ErrorsAttributeBean 的自动配置退出。

2020-05-30