我正在开发一个版本为2.2.0的 spring-boot 应用程序。
我想覆盖 spring-boot 默认提供的 bean。所以我spring.main.allow-bean-definition-overriding=true在我的workflow.properties文件中尝试过。
两个java文件中的代码是相同的,一个是默认提供的bean,另一个是我创建的。唯一的区别是,我创建的java文件将加载我提供的资源,而不是默认bean(来自spring-boot)加载默认资源。
我workflow.properties在我的主应用程序中加载这样的扩展org.springframework.boot.web.servlet.support.SpringBootServletInitializer:
@Override
protected SpringApplicationBuilder configure( SpringApplicationBuilder application )
{
application.application().setDefaultProperties( getProperties() );
return application.sources( WorkflowServiceApplication.class );
}
public static void main( String[] args )
{
// SpringApplication.run( WorkflowServiceApplication.class, args );
new SpringApplicationBuilder( WorkflowServiceApplication.class ).properties( "spring.config.name:workflow" )
.build()
.run( args );
}
static Properties getProperties()
{
Properties props = new Properties();
props.put( "spring.config.name", "workflow" );
props.put( "spring.config.location", "../conf/" );
return props;
}
Run Code Online (Sandbox Code Playgroud)
但我还是一样 ConflictingBeanException
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'stencilSetResource' for bean class [org.flowable.ui.modeler.rest.app.StencilSetResource] conflicts with existing, non-compatible bean definition of same name and class [com.myApplication.workflow.workflowservice.controllers.StencilSetResource]
at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.checkCandidate(ClassPathBeanDefinitionScanner.java:349) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:287) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.context.annotation.ComponentScanAnnotationParser.parse(ComponentScanAnnotationParser.java:132) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:290) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:587) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
... 15 common frames omitted
Run Code Online (Sandbox Code Playgroud)
检查spring-boot 文档后,我认为默认情况下 bean 定义覆盖是 false,但是为什么即使我在属性文件中将其设置为 true,覆盖也不起作用?
编辑:
在阅读完本文档后,看起来像是在刷新后告诉Environment读取属性workflow.properties而不是application.properties发生的配置ApplicationContext。在刷新发生之前,还会spring.main.*读取和加载一些属性。该链接建议通过实现加载属性源,所以我会尝试看看它是如何进行的。EnvironmentApplicationContextEnvironmentEnvironmentPostProcessor
编辑 2: 好的,所以我尝试了上面编辑中文档链接中给出的方法:
@Order( Ordered.LOWEST_PRECEDENCE )
public class CustomEvironmentPostProcesor implements EnvironmentPostProcessor
{
private static final String DEFAULT_MY_FRAMEWORK_PROPERTIES = "workflowProperties";
private static final String DEFAULT_MY_FRAMEWORK_PROPERTIES_LOCATION = "/workflow.properties";
private PropertiesPropertySourceLoader propertySourceLoader = new PropertiesPropertySourceLoader();
@Override
public void postProcessEnvironment( ConfigurableEnvironment environment,
SpringApplication application )
{
Resource workflowProperties = new ClassPathResource( DEFAULT_MY_FRAMEWORK_PROPERTIES_LOCATION );
List<PropertySource<?>> propertySource;
try
{
propertySource = propertySourceLoader.load( DEFAULT_MY_FRAMEWORK_PROPERTIES, workflowProperties );
if( propertySource != null )
{
environment.getPropertySources().addLast( propertySource.get( 0 ) );
}
}
catch( IOException e )
{
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我可以看到我在方法workflow.properties中Environment传递的实例中被加载postProcessEnvironment。
但是,我仍然遇到相同的异常。
小智 0
实际上,您的实施方法EnvironmentPostProcessor对我有用。我有一个类似的问题,我想申请spring.main.allow-bean-definition-overriding=true,但我无法使用application.properties,因为它必须通过共享库 Maven 依赖项。
IE
我简单地补充道:
package com.mycompany;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.support.ResourcePropertySource;
import java.io.IOException;
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
String propertiesFilePath = "classpath:/static.properties";
ResourcePropertySource resourcePropertySource;
try {
resourcePropertySource = new ResourcePropertySource(propertiesFilePath);
}
catch (IOException e) {
throw new RuntimeException("Resource " + propertiesFilePath + " doesn't exist");
}
environment.getPropertySources().addLast(resourcePropertySource);
}
}
Run Code Online (Sandbox Code Playgroud)
并确保src/main/resources/META-INF/spring.factories在以下位置配置文件:
org.springframework.boot.env.EnvironmentPostProcessor=com.rei.adapter.customer.rights.orchestration.kafka.CROAdapterEnvironmentPostProcessor
Run Code Online (Sandbox Code Playgroud)
构建我的库 jar 并在使用它的项目中刷新它后,我不再看到org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name ...错误并且本地主机启动成功。
| 归档时间: |
|
| 查看次数: |
1062 次 |
| 最近记录: |