resource component bean java spring autowired

java - component - ¿Puede Spring @Autowired Map?



spring autowired (4)

Aquí está el mapa

@Autowired private Map<String, ISendableConverter> converters;

e ISendableConverter

public interface ISendableConverter { ISendableMsg convert(BaseMessage baseMessage); String getType(); }

Hay algunas clases que implementan ISendableConverter

Quiero inyectarlos en los converters variables utilizando Spring Autowried.

la instancia de clase como valor y el resultado del método getType() como clave.

como éste

@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"; } }

¿es posible? ¿y cómo?


Intenta algo como esto, me funciona

private Map<String, ISendableConverter> converters; @Autowired public void setUploadServices(Set<ISendableConverter> converters){ this.conveters = converters.stream() .collect(Collectors.toMap(ISendableConverter::getType, Function.identity())); }

El mismo resultado se puede lograr usando la inyección de constructor:

private Map<String, ISendableConverter> converters; @Autowired public Foo(Set<ISendableConverter> converters) { this.conveters = converters.stream() .collect(Collectors.toMap(ISendableConverter::getType, Function.identity())); }


Pruebe con algo como @Resource - No he probado este código.

@Resource(name="converters") private Map<String, ISendableConverter> converters;

o

@Value("#{converters}") private Map<String, ISendableConverter> converters;

Desde Spring Docs

(..) los beans que están definidos como una colección o tipo de mapa no se pueden inyectar a través de @Autowired, porque la coincidencia de tipos no se aplica adecuadamente a ellos. Utilice @Resource para dichos beans, refiriéndose a la colección específica o al bean de mapa por nombre único.

Esto debería funcionar, solo si usted prepara converters como este:

<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>

Esta es también una pregunta similar:


Puede crear un mapa inicializado automáticamente con las claves de su elección utilizando la configuración de Spring Java:

En la clase anotada con la anotación @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; }

Que inyectas este mapa con:

@Resource() private Map<String, ISendableConverter> sendableConverters;

Opcionalmente, puede agregar alguna cadena de selección a su anotación @Resource si ha definido más mapas del mismo tipo.

De esta manera, todo lo que tiene que hacer es implementar ISendableConverter por su Spring Bean y aparecerá automáticamente en el mapa definido anteriormente. No es necesario crear elementos de mapa a mano para cada implementación.


Puedes hacer algo como esto:

@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); }); }