Spring Boot中MapStruct泛型Mapper注入找不到Bean如何解决
问题根因
你在抽象泛型父类中直接@Autowired注入带泛型参数的GenericMapper<E,T>和GenericRepository<E>时,Spring容器在父类初始化阶段无法确定泛型对应的实际实现类Bean,只有等子类指定了具体的E、T泛型参数后才能匹配到对应实现,因此会抛出找不到Bean的报错。
解决方案
步骤1:修改抽象通用Service实现,移除父类的自动注入,改为构造方法传参
public abstract class ServiceGenericImpl<E extends BaseEntity,T extends BaseDto> implements ServiceGeneric<T> { protected final GenericRepository<E> genericRepository; protected final GenericMapper<E,T> genericMapper; // 提供构造方法,由子类传入实际的Repository和Mapper实例 public ServiceGenericImpl(GenericRepository<E> genericRepository, GenericMapper<E, T> genericMapper) { this.genericRepository = genericRepository; this.genericMapper = genericMapper; } // 原有通用业务逻辑代码保持不变 }
步骤2:修正通用Mapper的泛型定义
你原有代码中toDTO方法的返回值写死为DTO,需要改为泛型参数T才能匹配泛型逻辑:
public interface GenericMapper<E extends BaseEntity, T extends BaseDto> { T toDTO(E entity); E toEntity(T dto); }
步骤3:业务子类实现时注入对应实例传给父类
编写具体业务的Service实现类时,直接注入当前业务对应的Mapper、Repository实例,调用父类构造方法传入即可,Spring会自动匹配MapStruct生成的Mapper实现Bean、以及持久层框架生成的Repository实现Bean:
@Service public class CityServiceImpl extends ServiceGenericImpl<City, CityDto> implements CityService { // 注入当前业务对应的具体实现 public CityServiceImpl(CityRepository cityRepository, CityMapper cityMapper) { super(cityRepository, cityMapper); } // 业务自定义逻辑写在这里即可 }
如果是其他业务比如人员,只需要对应写PersonServiceImpl继承ServiceGenericImpl<Person, PersonDto>,注入PersonRepository和PersonMapper即可,不需要重复写通用逻辑。
补充校验
如果使用Spring Data JPA作为持久层,需要保证业务Repository继承了你的GenericRepository接口,示例如下:
public interface CityRepository extends GenericRepository<City> { }
内容的提问来源于stack exchange,提问作者user5504616
相关产品推荐
相关产品推荐

