【问题标题】:How do I @Autowire @Component`s in an enum constructor?如何在枚举构造函数中 @Autowire @Component`s?
【发布时间】:2021-04-17 13:40:36
【问题描述】:

假设,我有一个类 ProviderService 带有一个 Map<ProviderEnum, Provider> 字段。那么这个类的构造函数如下

@Autowired
ProviderService(ProviderA provA, ProviderB provB, ...) {
    map.put(ProviderEnum.A, provA);
    map.put(ProviderEnum.B, provB);
    ...
}

Provider 是一个抽象类继承者,它的注解为@Component
然后我意识到至少有两种可能更好的方法:

  1. 使用EnumMap 来实现Map。现在,我使用HashMap
  2. 有一个Provider 字段 ProviderEnum 枚举并从ProviderService 完全删除地图。

第二个选项似乎是更清洁的解决方案,我开始这样写

enum ProviderEnum {
    A(/* ?WHAT DO I PUT HERE? */),
    B(/* Is it some kind of BeanFactory.getBean(ProviderB.class)? */),
    ...;

    private final Provider provider;
    
    ProviderEnum(Provider provider) {
        this.provider = provider;
    }
    
    public Provider getProvider() {
        return this.provider;
    }    
}

但是,我不知道应该在这些构造函数中添加什么,因为它肯定不同于使用 @Autowired 的通常情况。
我想我应该考虑使用BeanFactory 但是有没有办法构造函数注入它?我应该现场注入它吗? 还是坚持EnumMap更好?

【问题讨论】:

  • 枚举值是隐式静态的,静态是一种糟糕的设计模式。您似乎在这里遇到了一个 XY 问题:使用枚举作为鉴别器的预期目的是什么?
  • @chrylis-cautiouslyoptimistic- 我有一组我想访问的提供程序。我可以依赖Map<String, Provider>,但枚举似乎是一个更可靠的选择。因此,帖子末尾有一堆问题

标签: java spring dependency-injection enums autowired


【解决方案1】:

枚举是静态的,更好的方法是将某种类型的集合自动装配到您的服务中,就像这样

  1. 提供者接口(或您如何看待它)与
public interface Provider {
    // This can be your differentiator
    ProviderEnum getProviderType();
    void doSomeProviderThing();    
}
  1. 在您的 ProviderService 类中,您可以自动装配一个集合并使用 PostConstruct 来完成其余的工作
@Component
public class ProviderService {

    // This will autowire all providers as a collection
    @Autowired
    private  Collection<Provider> providers;
 
    @PostConstruct
    public void init() {
        providers.stream().foreach( provider -> {
            // Do you mapping with provider.getProviderType() if you still see value.
            // like map.put(provider.getProviderType(), provider);
        }); 
    }

}

【讨论】:

  • 最好的解决方案,但最好使用构造函数注入(这样可以在启动时创建Map&lt;String, Provider&gt;)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 2020-10-28
相关资源
最近更新 更多