spring @AutoWired Map을 사용할 수 있습니까?
지도 여기 있습니다.
@Autowired
private Map<String, ISendableConverter> converters;
그리고.ISendableConverter
public interface ISendableConverter {
ISendableMsg convert(BaseMessage baseMessage);
String getType();
}
구현하는 클래스가 몇 개 있습니다.ISendableConverter
변수에 주입하고 싶습니다.converters
용수철을 이용하여@Autowried
주석
값으로서의 클래스의 인스턴스 및 방법의 결과getType()
열쇠로
이것처럼 말이다.
@Component
public class SendableVoiceMsgConverter implements ISendableConverter {
@Override
public ISendableMsg convert(BaseMessage baseMessage) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getType() {
return "VOICE";
}
}
이것이 가능합니까?그리고 어떻게?
Spring Java 구성을 사용하여 원하는 키로 자동으로 초기화된 맵을 만들 수 있습니다.
수업 시간에 주석이 달린 것으로 주석을 달았습니다.@Configuration
주석:
@Autowired
private List<ISendableConverter> sendableConverters;
@Bean
public Map<String, ISendableConverter> sendableConvertersMap() {
Map<String, ISendableConverter> sendableConvertersMap = new HashMap<>();
for (ISendableConverter converter : sendableConverters) {
sendableConvertersMap.put(converter.getType(), converter);
}
return sendableConvertersMap;
}
이 맵에 다음을 삽입할 때보다:
@Resource()
private Map<String, ISendableConverter> sendableConverters;
선택적으로 일부 선택기 문자열을 에 추가할 수 있습니다.@Resource
같은 유형의 맵을 더 정의한 경우 주석을 입력합니다.
이런 식으로 구현하기만 하면 됩니다.ISendableConverter
당신의 스프링 빈에 의해 그리고 그것은 위에 정의된 지도에 자동으로 나타날 것입니다.각 구현에 대해 지도 항목을 수동으로 생성할 필요가 없습니다.
@Resource - 이 코드를 테스트하지 않았습니다.
@Resource(name="converters")
private Map<String, ISendableConverter> converters;
또는
@Value("#{converters}")
private Map<String, ISendableConverter> converters;
(...) 컬렉션 또는 지도 유형으로 정의된 콩은 유형 일치가 적절하게 적용되지 않기 때문에 @Autowired를 통해 주입할 수 없습니다.이러한 콩에 대해 @Resource를 사용합니다. 특정 컬렉션을 참조하거나 고유한 이름으로 콩을 매핑합니다.
이것은 당신이 준비하는 경우에만 효과가 있을 것입니다.converters
이런 콩:
<util:map id="converters" scope="prototype" map-class="java.util.HashMap"
key-type="java.lang.String" value-type="...ISendableConverter">
<entry key="VOICE" value="sendableVoiceMsgConverter" />
</util:map>
이것도 비슷한 질문입니다.
다음과 같은 작업을 수행할 수 있습니다.
@SuppressWarnings("unused")
private List<OneTypeImageLoader> imageLoaders;
private Map<String, OneTypeImageLoader> imageLoaderMap=new HashMap<>();
@Autowired
public void setImageLoaders(List<OneTypeImageLoader> imageLoaders) {
this.imageLoaders = imageLoaders;
imageLoaders.forEach(l-> {
imageLoaderMap.put(l.getType(), l);
});
}
이런 것을 시도해 보세요, 저에게 효과가 있습니다.
private Map<String, ISendableConverter> converters;
@Autowired
public void setUploadServices(Set<ISendableConverter> converters){
this.conveters = converters.stream()
.collect(Collectors.toMap(ISendableConverter::getType, Function.identity()));
}
생성자 주입을 사용해도 동일한 결과를 얻을 수 있습니다.
private Map<String, ISendableConverter> converters;
@Autowired
public Foo(Set<ISendableConverter> converters) {
this.conveters = converters.stream()
.collect(Collectors.toMap(ISendableConverter::getType, Function.identity()));
}
@Component("VOICE")
public class SendableVoiceMsgConverter implements ISendableConverter {
@Override
public ISendableMsg convert(BaseMessage baseMessage) {
// TODO Auto-generated method stub
return null;
}
}
형식 이름을 구성 요소 주석에 직접 추가하면 됩니다.
먼저 빈 이름을 반환 값과 같이 설정합니다.getType()
@Component("VOICE")
public class SendableVoiceMsgConverter implements ISendableConverter {
@Override
public ISendableMsg convert(BaseMessage baseMessage) {
// TODO Auto-generated method stub
return null;
}
}
다음과 같이 사용할 수 있습니다.
@Autowired
private Map<String, ISendableConverter> converters;
이 지도의 V형은 빈의 인스턴스이고, K형은 빈의 이름입니다.
이는 다음을 통해 달성할 수 있습니다.spring-componentmap
(https://github.com/krud-dev/spring-componentmap)
예를 들어 다음을 수행합니다.
public interface ISendableConverter {
ISendableMsg convert(BaseMessage baseMessage);
@ComponentMapKey
String getType();
}
@Component
public class SendableVoiceMsgConverter implements ISendableConverter {
@Override
public ISendableMsg convert(BaseMessage baseMessage) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getType() {
return "VOICE";
}
}
// Call the converter by type
@Component
class SendableMsgConverter {
// @ComponentMap replaces @Autowired in this case
@ComponentMap
private Map<String, ISendableConverter> converterMap;
public ISendableMsg convert(BaseMessage baseMessage) {
ISendableConverter converter = converterMap.get(baseMessage.getType());
return converter.convert(baseMessage);
}
}
고지 사항:공동 개발했습니다.spring-componentmap
더 일반적으로 만들고 다음과 같은 것을 만들 수 있습니다.
public interface BasicStrategy {
String getKey();
}
public final class StrategyMap<K extends BasicStrategy> extends HashMap<String, K> {
public StrategyMap(List<K> strategies) {
super(strategies.stream().collect(Collectors.toMap(K::getKey, Function.identity())));
}
@Override
public K get(Object key) {
BasicStrategy basicStrategy = super.get(key);
if (basicStrategy == null) {
throw new RuntimeException("No strategy found for key: '" + key + "'");
}
return (K) basicStrategy;
}
}
이제 이것을 사용할 수 있습니다.StrategyMap
다음과 같이 코드 주위의 모든 곳에서:
private StrategyMap<ISendableConverter> converters;
@Autowired
public Foo(List<ISendableConverter> converters) {
this.conveters = new StrategyMap<>(converters);
}
이 접근 방식은 다음을 생성합니다.StrategyMap
또한 값을 찾을 수 없는 경우의 논리를 중앙 집중화할 수 있습니다.
PS: 물론입니다.ISendableConverter
확장해야 합니다.BasicStrategy
interface 이름
언급URL : https://stackoverflow.com/questions/20918825/can-spring-autowired-map
'programing' 카테고리의 다른 글
ASP.Net 유효성 검사 요약으로 인해 페이지가 맨 위로 이동합니다. (0) | 2023.08.18 |
---|---|
빠른 클릭 시 Chrome에서 요소가 파란색으로 강조되는 것을 방지하기 위한 방법은 무엇입니까? (0) | 2023.08.18 |
Xcode 4에서 iOS 프로젝트에 정적 라이브러리 연결 (0) | 2023.08.13 |
Docker 및 MariaDB/MySQL - 원격 액세스를 사용하도록 my.cnf를 영구적으로 편집 (0) | 2023.08.13 |
Mocking boto3 S3 클라이언트 메소드 Python (0) | 2023.08.13 |