如何在 bean 类本身中放置 @Bean 工厂方法?

Posted

技术标签:

【中文标题】如何在 bean 类本身中放置 @Bean 工厂方法?【英文标题】:How to place @Bean factory method in the bean class itself? 【发布时间】:2019-08-08 22:12:30 【问题描述】:

我有一个包含从 JSON 文件反序列化的数据的类。这些数据应该在我的应用程序中可用,所以我想将它绑定为 bean。

为了保持反序列化逻辑和数据结构在一起,我想把@Bean注解的工厂方法放到数据类本身——像这样:

@Configuration
public class MyData 

    // factory method
    @Bean
    public static MyData loadMyData(ResourceLoader resourceLoader) throws IOException 
        try (InputStream input = resourceLoader.getResource("classpath:data.json").getInputStream()) 
            return new ObjectMapper().readValue(input, MyData.class);
         
    

    // data structure
    private Map<String, DataDetail> details;

    // ...

但是这失败了,因为@ComponentScan 现在找到了两个 bean 定义:

org.springframework.beans.factory.NoUniqueBeanDefinitionException:没有“org.example.MyData”类型的合格bean可用:预期的单个匹配bean但找到了2:myData,loadMyData

我也试过用@Component替换@Configuration,但结果是一样的。

我只是错过了类上的正确注释,还是无法将 @Bean 方法放在 bean 类本身中?

【问题讨论】:

看看Best way to load some JSON files into a Spring Boot application 你需要两个相同类型的bean吗?您可以将它们命名为唯一的并Autowire 对应一个 不,我只想要一颗豆子。但到目前为止,我还没有弄清楚如何在所描述的场景中得到这个。 【参考方案1】:

基本上我更喜欢带有 Spring Boot 的分层架构,例如 Configurationmodel 有两个不同的层

app.config

@Configuration
public class MyDataConfig 

// factory method
@Bean
public static MyData loadMyData(ResourceLoader resourceLoader) throws IOException 
    try (InputStream input = resourceLoader.getResource("classpath:data.json").getInputStream()) 
        return new ObjectMapper().readValue(input, MyData.class);
     
 


com.model

public class MyData 

// data structure
private Map<String, DataDetail> details;

    // ...

【讨论】:

【参考方案2】:

正如 Deadpool 回答的那样,您应该将 MyData 类与 @Configurtion 类分开。@Configuration 使用 @Component 进行元注释,因此一旦您使用 @Configuration 注释 MyData,Spring 也将其与普通 bean 关联起来,这就形成了 MyData bean 的双重定义。

【讨论】:

以上是关于如何在 bean 类本身中放置 @Bean 工厂方法?的主要内容,如果未能解决你的问题,请参考以下文章

创建在类路径资源[applicationcontext]中定义名为“工厂”的bean时出错。:在设置bean属性“dataSource”时,无法解析对bean“dataSource”的引用;嵌套异常是

我们可以有一个工厂类作为spring bean,并有一个工厂方法根据条件返回多个spring bean吗?

springMVC的核心是啥

SpringIOC容器-xml配置bean-工厂方式配置Bean

Spring - 从工厂类注入 bean

Spring关于Bean