从this问题开始,是否可以向地图注入枚举?
例如,我有枚举:
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
答案 0 :(得分:1)
不太确定要做什么,但是从我的角度来看,您不需要此映射。我假设您想知道在某些情况下使用哪种实现。因此,只需自动连接一个列表或一组接口并对其进行遍历,以找到正确的实现。 (我用Java展示了这些东西)
@Autowired
List<SomeInterface> someInterfaces;
在此列表中,您将拥有此接口的所有注入的实现。如果仍然需要一个Enum来查看要使用的实现,只需将此作为属性添加到每个实现类中。因此,您可以通过其实现获取Enum值。
编辑: 创建一个配置类并自动连接实现列表。在此配置类中,您将创建地图的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;
答案 1 :(得分:1)
@Qualifier
注释。它不是要命名bean,而是要帮助Spring在多个中选择单个自动装配候选。 @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 }!!
}
}
}