如何在春季注入(自动装配)bean以枚举作为映射键进行映射? [英] How to inject(autowired) beans to map with enum as map key in spring?

查看:174
本文介绍了如何在春季注入(自动装配)bean以枚举作为映射键进行映射?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解到在春季,我可以通过如下所示的配置名称自动接线/注入Map<String, SomeBeanInterface>:

I've learned that in spring, i can autowire/inject into Map<String, SomeBeanInterface> by configured name like below:

public interface DummyInterface{
}

@Component("impl1")
public class Impl1 implement DummyInterface{
}

@Component("impl2")
public class Impl2 implement DummyInterface{
}

public class SomeUsage{
    @Autowired
    private Map<String, DummyInterface> mapping;
    // ...
}

并按字符串检索Component作为键,例如:

and retrieve the Component by string as key like:

SomeUsage use = new SomeUsage();
DummyInterface dummy = use.getMapping().get("impl1");
// do sth...

但是,如果bean映射的键不是String类型,而是用户定义的Enum类型,我应该如何将这些bean注入enumMap中?

However, if the key of bean mapping is not the type of String, but the type of user defined Enum, how should i inject the beans into the enumMap?

我已经阅读了一些文章,并了解到可以通过xml文件对其进行配置.但是似乎xml配置与<Enum, Bean>对紧密耦合,这意味着每次我添加一个新的<Enum, Bean>对时,我都必须同步配置文件,与我当前的解决方案,就是仍然使用<String, Bean>集合,并由我自己维护java代码中的<Enum, String>映射.有没有更好的解决方案来解决这个问题?还是我想念什么?

I've read some post and learned that it can be configured by xml file. But it seems to be that the xml configuration is tightly coupled with the <Enum, Bean> pair, which means that each time if i add a new <Enum, Bean> pair, i have to synchronize the configuration file, it seems that there's no difference comparing to my current solution, that is, still using the <String, Bean> collection and maintain the <Enum, String> mapping in java code by my own. Are there any better solution to handle this? Or do i miss something?

推荐答案

您总是必须定义Enum和Spring Bean之间的映射,但是您可以强制组件必须声明它们映射到的枚举.您可以实现以下创建界面:

You always have to define mapping between Enum and Spring Bean but you can enforce that components have to declare to which enumeration they are mapped to. You can acheive that creating interface like:

public interface EnumMappedBean {
    SomeEnum getSomeEnum();
}

然后,要映射的每个组件都必须实现它.

Then every component that you want to be mapped has to implement it.

@Component
public class Bean1 implements EnumMappedBean {
    @Override
    public SomeEnum getSomeEnum() {
        return SomeEnum.ENUM1;
    }
}

@Component
public class Bean2 implements EnumMappedBean {
    @Override
    public SomeEnum getSomeEnum() {
        return SomeEnum.ENUM2;
    }
}

然后,您就可以通过其映射来映射每个组件.

Then you can map each of this components by it's enumaration.

@Configuration
public class AppConfig {
    @Bean
    public Map<SomeEnum, EnumMappedBean> getBeansMappedByEnum(@NonNull Collection<EnumMappedBean> enumBeans) {
        return enumBeans.stream()
                .collect(toMap(EnumMappedBean::getSomeEnum, Function.identity()));
    }
}

然后在任何需要的地方注入.

And inject wherever you want.

@Service
public class SomeOtherBean {

    private Map<SomeEnum, EnumMappedBean> beansMappedByEnum;

    @Autowired
    public SomeOtherBean(@NonNull Map<SomeEnum, EnumMappedBean> beansMappedByEnum) {
        this.beansMappedByEnum = beansMappedByEnum;
    }
}

在config类中,您还可以验证每个组件都声明唯一的非null枚举值.

In config class you can also validate that every component declare uniqe, non-null enum value.

这篇关于如何在春季注入(自动装配)bean以枚举作为映射键进行映射?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆