在通用超类中自动装配通用组件
Posted
技术标签:
【中文标题】在通用超类中自动装配通用组件【英文标题】:Autowiring a generic component in a generic superclass 【发布时间】:2016-09-03 20:56:04 【问题描述】:我在一个Spring 4.0(使用Spring Boot)的环境中有以下情况:
映射界面:
public interface EntityModelMapper<ENTITY extends AbstractEntity, MODEL extends AbstractModel>
映射实现:
@Component
public class ProductEntityModelMapper implements EntityModelMapper<Product, ProductModel>
服务:
public interface CrudService<MODEL extends AbstractModel>
我想做一个像这样的抽象超类服务:
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;
所以我可以有这样的实现:
@Service
public ProductCrudService extends AbstractCrudService<Product, ProductModel>
public void someMethod(Product product)
ProductModel model = getMapper().map(product);
但是 Spring 告诉我它找不到 EntityModelMapper 的合格 bean 来注入服务类。这种情况是否可能,我做错了什么,还是我在推动 Spring 的依赖注入的限制?
堆栈跟踪:
org.springframework.beans.factory.BeanCreationException: 创建名为“productCrudService”的 bean 时出错: 注入自动装配的依赖项失败; 嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段: 私人 com.flycatcher.seagull.mapper.EntityModelMapper com.flycatcher.seagull.facade.service.crud.AbstractCrudService.mapper; 嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 没有为依赖找到 [com.flycatcher.seagull.mapper.EntityModelMapper] 类型的合格 bean: 预计至少有 1 个 bean 有资格作为此依赖项的自动装配候选者。 依赖注解:@org.springframework.beans.factory.annotation.Autowired(required=true)
【问题讨论】:
【参考方案1】:据此: https://spring.io/blog/2013/12/03/spring-framework-4-0-and-java-generics 从Spring 4.0版本开始就可以了。
这对我也不起作用。 (同样的例外,我使用的是 4.2.3)。 所以尝试升级到最新版本——4.2.6。
如果还是不行, 您可以改为使用 @Qualifier 注释和自动装配 EntityModelMapper 作为子类中的接口,并将 getMapper 定义为抽象:
@Component
@Qualifier("productEntityModelQualifier")
public class ProductEntityModelMapper implements EntityModelMapper<Product, ProductModel>
然后在 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);
【讨论】:
直接在服务实现中注入 EntityModelMapper以上是关于在通用超类中自动装配通用组件的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Boot 中实现通用 JPA 存储库 - 它可以自动装配到任何实体/类类型的 Spring 服务中
无法在 Spring Boot 的组件类中自动装配推土机 Mapper
通过注解实现自定义Spring Boot Starter自动装配
如何自动装配在 SpringBoot 应用程序中具有带参数的构造函数的组件
Spring框架开发底层的@Component 通用组件模式@Service 服务模式@Configuration 配置模式等注解装配技术详解