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

Jea*_*ana 6 spring-boot spring-boot-configuration

我维护了一个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);
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

And*_*son 9

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 的自动配置退出。


小智 5

更简单的解决方案是spring.main.allow-bean-definition-overriding=trueapplication.properties.

参考