Spring Bean 无法定位配置属性 Bean

huangapple go评论70阅读模式
英文:

Spring Bean Unable to Locate Configuration Properties Bean

问题

我正在使用TestNG和Spring Framework(以及Spring Boot)编写测试,但在应用程序上下文无法定位特定配置属性bean时遇到了问题。

设置涉及两个不同的配置,都被测试引用。导致问题的设置的简单表示如下:

@EnableConfigurationProperties
public class SomePropertyConfiguration {

    @Bean(name = "someConfiguration")
    @ConfigurationProperties(prefix = "test.prefix")
    public CustomPropertyClass customPropertyClass(){
        return new CustomPropertyClass();
    }

}

@Configuration
public class SomeConfiguration {

    public ISomethingApi somethingApi(CustomPropertyClass customPropertyClass){
        return new SomethingApi(customPropertyClass.getProperty());
    }
}

测试的设置非常简单,只是为了测试一些基本属性:

@TestPropertySource("classpath:/test.properties")
@ContextConfiguration(classes = { SomePropertyConfiguration.class, SomeConfiguration.class })
public class SomethingApiTest extends AbstractTestNGSpringContextTests {

    @Inject
    private ISomethingApi somethingApi;

    @Test
    public void test(){
        // 做一些操作
    }
}

这些设置的最终结果是,SomethingApi 的配置无法找到有效的类型为 CustomPropertyClass 的bean。

值得注意的是,如果从测试中删除 SomeConfiguration,并直接将 CustomPropertyClass 注入到测试中,一切正常,并且属性的值是预期的,这是问题最令人困惑的地方 - 因此似乎有些东西导致Spring不能正确处理bean的装配顺序。我在其他项目中有类似的设置,它们都按预期运行,但我无法找到可能导致此行为的任何有意义的差异(这两个项目都使用相同版本的Spring和Spring Boot的主要版本)。

编辑:

我尝试过在 SomePropertyConfiguration 上使用和不使用 @Configuration,结果没有变化。在其他项目中,与此正常工作的引用的项目一样,属性配置类不包括该显式注释,所以我在上面的主要示例中省略了它。我还尝试在第二个配置中使用属性bean的 @Autowired 字段,并以这种方式引用它作为依赖项,而不是作为参数(以防影响装配bean的顺序或其他问题),但结果也没有改变。

我正在使用Spring Framework 5.1.7.RELEASE 和Spring Boot 2.0.9.RELEASE

英文:

I am writing a test using TestNG and Spring Framework (along with Spring Boot), and am running into the application context being unable to locate a particular configuration properties bean.

The setup involves two separate configurations, both referenced by the test. A simple representation of the setup causing the issue would involve these configurations:

@EnableConfigurationProperties
public class SomePropertyConfiguration {

    @Bean(name = "someConfiguration")
    @ConfigurationProperties(prefix = "test.prefix")
    public CustomPropertyClass customPropertyClass(){
        return new CustomPropertyClass();
    }

}

@Configuration
public class SomeConfiguration {

    public ISomethingApi somethingApi(CustomPropertyClass customPropertyClass){
        return new SomethingApi(customPropertyClass.getProperty());
    }
}

The test is setup in a simple way, just to test a couple base properties:

@TestPropertySource("classpath:/test.properties")
@ContextConfiguration(classes = { SomePropertyConfiguration.class, SomeConfiguration.class })
public class SomethingApiTest extends AbstractTestNGSpringContextTests {

    @Inject
    private ISomethingApi somethingApi;

    @Test
    public void test(){
        // Do stuff
    }
}

The end result of these setups is an exception where the configuration for SomethingApi cannot find a valid bean of type CustomPropertyClass.

It is worth noting that if SomeConfiguration is removed from the test, and CustomPropertyClass is injected into the test directly, everything works and the properties are the expected values, which is what is most perplexing about the issue - so something seems to be causing spring to not deal with order of wiring for beans correctly. I have similar setups in other projects which operate as expected, but I have been unable to find any meaningful differences that might cause this behavior (both projects are on the same major version of Spring and Spring Boot)

EDIT:

I have tried with and without @Configuration on SomePropertyConfiguration, without any change in results. In the other project referenced with this working, the property configuration class does not include that explicit annotation, so I left it off in the main example above. I also tried using an @Autowired field of the property bean in the second configuration and referencing it that way for the dependency, instead of as a parameter (in case that impacted order of wiring or something), which also had no impact on the results.

I am using Spring framework 5.1.7.RELEASE, and Spring Boot 2.0.9.RELEASE

答案1

得分: 1

经过进一步的调查,我在日志中找到了以下内容:

已存在名为 'someConfiguration' 的 bean 定义。此顶级 bean 定义被视为覆盖。

原来在这种情况下,我的项目中的命名约定导致属性类 bean 的名称与项目的总体配置 bean 发生了冲突。这两个 bean 和配置类似乎共享一个命名空间,如果它们发生冲突,不会直接导致崩溃或错误。

英文:

After some additional investigation, I found the following in the logs

a definition for bean 'someConfiguration' already exists. This top-level bean definition is considered as an override

it turns out that in this circumstance, the naming conventions in my project had caused a collision between the name of the property-class bean, and the project's overall configuration bean. Both beans and configuration classes appear to share a namespace, and will not cause a crash/error (directly) if they collide

huangapple
  • 本文由 发表于 2020年8月4日 09:55:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/63239176.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定