Spring注入的bean不是@Configuration中指定的bean

Spring注入的bean不是@Configuration中指定的bean,spring,spring-boot,kotlin,properties-file,spring-annotations,Spring,Spring Boot,Kotlin,Properties File,Spring Annotations,最近,我在Spring中连接bean时出错,导致无法复制的行为。当部署应用程序时,使用了@Configuration中定义的@String类型的另一个bean的值,而不是源于@Value的属性注入内容(请参阅下面的完整演示代码) 我发现令人费解的是,在本地运行(包括单元测试)时,一切都按预期工作,输出是foo而不是kaboom,并且这种“bean交换”完全是在部署时发生的,而不是“没有符合条件的bean”错误 注释掉的行显示了修复,我认为它使配置与中的配置相似 我的设置有什么问题?什么会使所示代

最近,我在Spring中连接bean时出错,导致无法复制的行为。当部署应用程序时,使用了
@Configuration
中定义的
@String
类型的另一个bean的值,而不是源于
@Value
的属性注入
内容(请参阅下面的完整演示代码)

我发现令人费解的是,在本地运行(包括单元测试)时,一切都按预期工作,输出是
foo
而不是
kaboom
,并且这种“bean交换”完全是在部署时发生的,而不是“没有符合条件的bean”错误

注释掉的行显示了修复,我认为它使配置与中的配置相似

我的设置有什么问题?什么会使所示代码(即没有修复)使用
kaboom
String
而不是
foo
属性

import org.springframework.boot.autoconfigure.springboot应用程序
导入org.springframework.boot.runApplication
@SpringBoot应用程序
开放类演示应用程序
趣味主线(args:Array){
运行应用程序(*args)
}
import org.springframework.beans.factory.annotation.Value
导入org.springframework.context.annotation.Bean
导入org.springframework.context.annotation.Configuration
@配置
开放类配置{
//…原始代码中不是字符串类型的bean。。。
@豆子
打开有趣的beanBomb():字符串{
返回“kaboom”
}
@豆子
//修正:
//@Value(\${stuff})
打开有趣的beanStuff(stuff:String):stuff{
退货
}
}
import org.springframework.beans.factory.annotation.Value
导入org.springframework.stereotype.Component
@组成部分
类Stuff(@Value(\${Stuff})val Stuff:String)
import org.springframework.beans.factory.annotation.Autowired
导入org.springframework.stereotype.Component
导入javax.annotation.PostConstruct
@组成部分
类初始化{
@自动连线
私有lateinit var stuff:stuff
@施工后
fun init(){
println(“stuff:+stuff.stuff)
}
}
导入静态org.junit.jupiter.api.Assertions.assertEquals;
导入org.junit.jupiter.api.Test;
导入org.junit.jupiter.api.extension.extensedWith;
导入org.springframework.boot.test.mock.mockito.SpyBean;
导入org.springframework.test.context.TestPropertySource;
导入org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@TestPropertySource(属性={“stuff=testFoo”})
类DemoApplicationTests{
@间谍
私人物品;
@试验
无效测试(){
assertEquals(“testFoo”,stuff.getStuff());
}
}
另外,一旦应用了修复程序,
Stuff
中的
@Value
注释是否必要?如果我取消对修复的注释,请从
Stuff
中删除
@Value
,并向测试通过的测试类添加以下注释:

@ContextConfiguration(classes={Config.class})

但是当我运行应用程序时,它会打印出
kaboom

,您可以检查bean的创建顺序。如果bean是在我看来之前创建的,Spring IoC容器按类型注入值,即
kaboom
,并且由于默认情况下任何类型的bean都是单例的,
Stuff
的实例即使用
@component
注释也不会生效


在您的测试中,您正在手动加载配置,其中
Config
中定义的
Stuff
bean被注入,而不是
Stuff
@component

注释。问题是注释需要在参数上进行,而不是在函数上。 以您的方式,Spring正在寻找一个满足
String
类型的bean,并且有一个
String
类型的bean是由函数
beanBomb()
生成的。如果像这样移动注释,则应消除歧义

@Bean
打开有趣的beanStuff(@Value(\${stuff})stuff:String):stuff{
退货
}

我想补充一点,有一个类型为
String
的bean有点不寻常,但我想如果你不想使用属性/yaml文件,它会允许你根据配置文件更改
字符串。

所以原始代码的问题是我在两个地方创建bean
东西
@Bean
vs
@Component
),其中一个从
@Value
注释中获取参数,另一个从
Config
中创建的
字符串
bean中获取参数。当我在本地运行时,Spring创建了
@组件
注释
填充
填充
来自
@Value
,而在部署应用程序时Spring必须创建了
@Bean
注释的
Stuff
,其中
Stuff
来自
beanBomb()
。正确吗?如果是这样的话,很遗憾Spring没有警告多个bean声明,而是从批中挑选任何一个。是的,可能是..您可以添加一个调试器点或添加一些日志消息,只是为了确定bean的创建顺序,其他选项是使用
@Priority
@order
annota将
@Component
注释放在
Stuff
类上,同时在java配置(带有
@Bean
注释的方法)中定义它有什么意义?
// application.properties
stuff=foo