2016-05-09 5 views
0

habe ich die folgende Situation in einem Frühling-4.0 (mit Spring Boot) Umgebung:eine generische Komponente in einem generischen Super autowiring

Mapping-Schnittstelle:

public interface EntityModelMapper<ENTITY extends AbstractEntity, MODEL extends AbstractModel>{ } 

Mapping Implementierung:

@Component 
public class ProductEntityModelMapper implements EntityModelMapper<Product, ProductModel>{ } 

Service:

public interface CrudService<MODEL extends AbstractModel>{ } 

Und ich will diese eine abstrakte Superklasse Dienst wie tun:

public abstract AbstractCrudService<ENTITY extends AbstractEntity, MODEL extends AbstractModel> implements CrudService<MODEL>{ 

@Autowired 
private EntityModelMapper<ENTITY, MODEL> mapper; 

    public EntityModelMapper<ENTITY, MODEL> getMapper(){ 
     return mapper; 
    } 
} 

So kann ich Implementierungen gefällt das:

@Service 
public ProductCrudService extends AbstractCrudService<Product, ProductModel>{ 

    public void someMethod(Product product){ 
    ProductModel model = getMapper().map(product); 
    } 

} 

Aber Frühling erzählt Ich finde es nicht, dass berechtigte Beans von EntityModelMapper in die Serviceklassen injizieren. Ist dieses Szenario möglich und ich mache etwas falsches oder dränge ich die Grenzen der Abhängigkeits-Injektion von Spring?

Stacktrace:

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'productCrudService': 
Injection of autowired dependencies failed; 
nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: 
private com.flycatcher.seagull.mapper.EntityModelMapper 
com.flycatcher.seagull.facade.service.crud.AbstractCrudService.mapper; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [com.flycatcher.seagull.mapper.EntityModelMapper] found for dependency: 
expected at least 1 bean which qualifies as autowire candidate for this dependency. 
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Antwort

1

Nach dieser: https://spring.io/blog/2013/12/03/spring-framework-4-0-and-java-generics Es ist möglich, seit Frühjahr Version 4.0.

Das hat mir auch nicht geholfen. (gleiche Ausnahme und ich verwende 4.2.3). Versuchen Sie also, auf die neueste Version zu aktualisieren - 4.2.6.

Wenn es immer noch nicht funktioniert, Sie stattdessen die Anmerkung @Qualifier verwenden können und EntityModelMapper als Schnittstelle in Ihrer Unterklasse autowire und definieren getMapper als Zusammenfassung:

@Component 
    @Qualifier("productEntityModelQualifier") 
    public class ProductEntityModelMapper implements EntityModelMapper<Product, ProductModel>{ } 

und dann in ProductCrudService :

@Service 
public ProductCrudService extends AbstractCrudService<Product, ProductModel>{ 

    @Autowired 
    @Qualifier("productEntityModelQualifier") 
    EntityModelMapper<Product, ProductModel> mapper; 

    @Override 
    protected EntityModelMapper<Product, ProductModel> getMapper(){return mapper;} 

    public void someMethod(Product product){ 
    ProductModel model = getMapper().map(product); 
    } 

} 
+0

Injection der EntityModelMapper direkt in der Service-Implementierung funktioniert für mich. Ich möchte es in die abstrakte Klasse einfügen, so dass jede Service-Implementierung Zugriff auf ihre spezifische EntityModelMapper-Implementierung hat. (d. h. ProductCrudService wird zur Laufzeit über einen EntityModelMapper verfügen.) –

+1

Ich habe verstanden, was Sie wollen. Lies den ersten Abschnitt meiner Antwort – aviad

Verwandte Themen