问题描述
Spring
Boot的ErrorAttributes
bean由定义ErrorMvcAutoConfiguration
。带有注释,@ConditionalOnMissingBean
因此如果ErrorAttributes
已经定义了bean
,它将取消。由于ErrorsConfig
类定义的Bean
试图覆盖Boot的ErrorAttributes
bean而不是使其退出,因此ErrorsConfig
必须在Boot的ErrorMvcAutoConfiguration
类之后对您的类进行处理。这意味着您的起动器有订购问题。
可以使用@AutoConfigureBefore
和来控制自动配置类的处理顺序@AutoConfigureAfter
。假设ErrorsConfig
本身就是在其中注册的自动配置类spring.factories
,则可以通过使用注释解决问题@AutoConfigureBefore(ErrorMvcAutoConfiguration.class)
。进行此更改后,ErrorsConfig
将ErrorAttributes
在ErrorMvcAutoConfiguration
尝试进行定义之前定义其bean,这将导致BootErrorsAttribute
Bean 的自动配置退出。
解决方法
我维护了一个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