当前位置: 首页 > 知识库问答 >
问题:

是否可以使用枚举键注入映射?

丌官晔
2023-03-14

从这个问题,有可能注入map与枚举?

例如,我有枚举:

class enum SomeEnum (val value) {
  ONE("one"),
  TWO("two"),
  THREE("three")
}

我有一些与实现的接口:

interface SomeInterface {
}

@Component
@Qualifier("one")
class OneClass: SomeInterface {
...
}

@Component
@Qualifier("two")
class TwoClass: SomeInterface {
...
}

@Component
@Qualifier("three")
class ThreeClass: SomeInterface {
...
}

但这样的注入不起作用:

@Component
@ConfigurationProperties
class SomeProperties {
   @Autowired
   lateinit var someMap: Map<SomeEnum, SomeInterface>
}

我想自动注入someMap。如何修复它,在spring框架端生成这样的代码?

var someMap: Map<SomeEnum, SomeInterface> = Map.of(ONE, oneClass,
                                                   TWO, twoClass,
                                                   THREE, threeClass)

// Where oneClass, twoClass, threeClass - beans instances

共有2个答案

胡利
2023-03-14

不太确定你想做什么,但从我的观点来看,你不需要这个映射。我假设您想知道在特定情况下使用哪个实现。因此,只需自动连接一个列表或一组接口,并通过它进行迭代,以找到正确的实现。(我用Java展示这些东西)

@Autowired
List<SomeInterface> someInterfaces;

在此列表中,您将看到该接口的所有注入实现。如果仍然需要一个枚举来查看要使用哪个实现,只需将其作为属性添加到每个实现类中即可。所以你可以通过它的实现来获得枚举值。

编辑:创建一个配置类并自动连接实现列表。在这个配置类中,您创建了地图的一个Bean。

@Configuration
public class MyMapConfig {

    @Autowired
    List<SomeInterface> someInterfaces;

    @Bean
    public Map<SomeEnum, SomeInterface> myMap() {
        Map<SomeEnum, SomeInterface> map = new HashMap<>();
        someInterfaces.forEach(s -> {
            // logic here to add correct Enum to its implementation.
            map.put(SomeEnum.A, s);
        });
        return map;

    }

    public enum SomeEnum {
        A, B, C
    }
}

然后,您可以将地图自动关联到任意位置:

@Autowired
Map<SomeEnum, SomeInterface> myMap;
冯枫
2023-03-14
  1. 首先,你误用了@Qualifier注释。它的目的不是命名bean,而是帮助Spring在多个autowire候选者中选择单个autowire候选者@Qualifier仅在注入点有意义-对于类属性,可以与@Autowired成对使用
@Autowired
@Qualifier("one")
lateinit var someImpl: SomeInterface

或用于注入方法/构造函数参数

@Bean
fun createSomeService(@Qualifier("two") someImpl: SomeInterface): SomeService {
   return SomeService(someImpl)
}

//or

class SomeService(@Qualifier("three") private val someImpl: SomeInterface) { 
    ... 
}

命名bean的正确方法是简单地@Component("name")(或@Service("name")

interface SomeInterface

@Component("one")
class OneClass: SomeInterface

@Component("two")
class TwoClass: SomeInterface

@Component("three")
class ThreeClass: SomeInterface

@Component
@ConfigurationProperties
class SomeProperties(implMap: Map<String, SomeInterface>) {

    val someMap: Map<SomeEnum, SomeInterface> = implMap.mapKeys {
        SomeEnum.values().firstOrNull { e -> e.value == it.key }!!
    }
}

更新:

或使用现场注入(不推荐

@Component
@ConfigurationProperties
class SomeProperties {
    private lateinit var someMap: Map<SomeEnum, SomeInterface>

    @Autowired
    private lateinit var implMap: Map<String, SomeInterface>

    @PostConstruct
    fun initMap() {
        someMap = implMap.mapKeys {
            SomeEnum.values().firstOrNull { e -> e.value == it.key }!!
        } 
    }
}
 类似资料:
  • 问题内容: 我正在尝试将我的某些Obj-C类转换为Swift。还有其他一些Obj- C类仍在该转换后的类中使用枚举。我在“预发布文档”中进行了搜索,但找不到它,或者我错过了它。有没有办法在Obj- C类中使用Swift枚举?或指向此问题的文档的链接? 这就是我在旧的Obj-C代码和新的Swift代码中声明枚举的方式。 我以前的Obj-C代码: 我的新Swift代码: 更新: 从答案。在Swift低

  • 我正在尝试使用spring injection注入到枚举中。像这样: 我的Carparts bean在configuration类中定义如下: 但不管我得到的是车体注射的空值。任何帮助都将不胜感激。

  • 问题内容: 我的Java模型上有一个枚举类型,我想映射到数据库中的表。我正在使用“hibernate注释”,但我不知道该怎么做。由于我搜索的答案比较旧,我想知道哪种方法最好? 提前致谢 问题答案: 除了注释,您还需要其他东西吗?例如,以下枚举: 可以这样使用和注释: 您可以使用批注的enum属性指定枚举应如何在数据库中持久化。指定该枚举将作为整数值保留。在这里,设置为将永久保存为0,保留为1,依此

  • 问题内容: 我的Java模型上有一个枚举类型,我想映射到数据库中的表。我正在使用休眠注释,但我不知道该怎么做。由于我搜索的答案比较旧,我想知道哪种方法最好? 提前致谢 问题答案: 除了注释,您还需要其他东西吗?例如,以下枚举: 可以这样使用和注释: 您可以使用批注的enum属性指定枚举应如何在数据库中持久化。指定该枚举将作为整数值保留。在这里,设置为将永久保存为0,保留为1,依此类推。 替代方法是

  • 我有上面的列举 @JsonValue公共字符串getValue(){return value;} 部分和一个示例测试类,如。。。 公开课Foo{ 这个测试类打印出来 @jsonValue在作为map键的枚举字段上使用时不工作。 序列化映射时是否有方法将此枚举用作键? 谢谢

  • 问题内容: Python 3.4引入了一个新模块,该模块向该语言添加了枚举类型。的文档提供了一个示例来演示如何扩展它: 此示例还演示了一个问题:在property方法中,定义了一个常量,该常量通常在类级别定义- 但是尝试在a级别内执行此操作只会将其添加为枚举的成员之一,因此,在方法内部定义。 如果该类想在其他方法中使用此常量,则也必须在其中定义它,这显然不是理想的选择。 有什么方法可以在中定义类常