spring.main.allow-bean-definition-overriding=true 被忽略并抛出 ConflictingBeanException

Akk*_*kki 7 java spring-boot

我正在开发一个版本为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.propertiesEnvironment传递的实例中被加载postProcessEnvironment

但是,我仍然遇到相同的异常。

小智 0

实际上,您的实施方法EnvironmentPostProcessor对我有用。我有一个类似的问题,我想申请spring.main.allow-bean-definition-overriding=true,但我无法使用application.properties,因为它必须通过共享库 Maven 依赖项。

IE

  1. 我简单地补充道:

     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)
  2. 并确保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 ...错误并且本地主机启动成功。