如何在Spring中将注入(自动装配)的bean与枚举作为Map键映射?

14 浏览
0 Comments

如何在Spring中将注入(自动装配)的bean与枚举作为Map键映射?

我了解到在春天,我可以按照下面的方式通过配置的名称将Map自动装配/注入:

public interface DummyInterface{
}
@Component("impl1")
public class Impl1 implement DummyInterface{
}
@Component("impl2")
public class Impl2 implement DummyInterface{
}
public class SomeUsage{
    @Autowired
    private Map mapping;
    // ...
}

并且可以通过字符串作为键来获取Component,例如:

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

然而,如果bean映射的键不是String类型,而是用户自定义的Enum类型,那么我应该如何将bean注入到enumMap中呢?

我阅读了一些帖子并了解到它可以通过xml文件进行配置。但是看起来xml配置与对紧密耦合,这意味着每次如果我添加一个新的对,我都必须同步配置文件,这似乎与我的当前解决方案没有什么区别,即仍然使用集合,并在Java代码中自己维护映射。是否有更好的解决方案来处理这个问题?或者我错过了什么?

0
0 Comments

在Spring中,我们经常需要将枚举类与Spring Bean进行映射。但是,我们希望能够强制要求组件声明它们映射到哪个枚举值。为了实现这一点,我们可以创建一个接口EnumMappedBean,其中包含一个getSomeEnum方法,用来返回该组件映射的枚举值。

然后,我们需要让每个组件实现这个接口。例如,我们可以创建Bean1和Bean2类,它们分别实现了EnumMappedBean接口,并在getSomeEnum方法中返回相应的枚举值。

接下来,我们可以通过枚举值将每个组件进行映射。在AppConfig类中,我们可以定义一个方法getBeansMappedByEnum,该方法接收一个EnumMappedBean的集合,并将其转换成一个以枚举值为键、EnumMappedBean为值的Map。

然后,我们可以在需要的地方注入这个Map。例如,在SomeOtherBean类中,我们可以定义一个构造函数,接收这个Map作为参数。

需要注意的是,在配置类中,我们可以验证每个组件是否声明了唯一且非空的枚举值。

如果我们有一个Map,需要将其替换为Map,我们应该如何做呢?使用(name = "...")注解吗?

恐怕没有现成的解决方案来实现这一点。默认的依赖注入行为是基于bean的类型/名称的,无法通过简单地传递一些参数来更改它。

虽然我们可以使用按名称注入来处理这个问题,但这种方式需要所有使用该Bean的用户都按名称进行注入。只有在使用@Qualifier注解时,我们需要知道bean的名称。而使用@Autowired或@Inject注解时,我们可以根据类型或父类型获取受管实例。例如在上述代码中,SomeOtherBean对于配置类中的名称一无所知,依赖关系是根据是否存在Map作为受管组件来解析的。

0
0 Comments

问题的出现的原因是在使用Spring的自动装配(autowired)功能时,当一个接口有多个实现类时,无法确定要注入哪个实现类。在这种情况下,需要使用限定符(qualifier)来指定要注入的实现类。

解决方法是在注入的字段上添加限定符,以指定要注入的实现类。在这个例子中,使用了一个枚举(Enum)作为Map的键,所以需要使用EnumMap来实现这个功能。

具体的解决方法如下:

@Qualifier("impl2") //注入impl2实现类
private EnumMap mapping;

当一个接口有多个实现类时,如果不添加限定符,Spring无法确定要注入哪个实现类。在注入实现类到Map中时,需要知道要注入的实现类的类型,在取出实现类时也需要知道要取出的是哪个实现类。

更多关于EnumMap的信息,可以参考[这里](https://stackoverflow.com/a/12669569/9092901)。

请检查注解的value字段,并参考[这里](https://stackoverflow.com/a/20180762/8510613)。

0