无法使用 spring componentModel 为修饰的 MapStruct 映射器创建 bean

Cannot create bean for decorated MapStruct mapper with spring componentModel

我目前正在使用 Spring componentModel 设置一个 MapStruct 映射器,到目前为止一切正常,各个子映射器可以自动连接并按预期注入。但是,使用装饰映射器会在加载 ApplicationContext 时导致以下失败:

Error creating bean with name 'exampleMapperImpl': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type '...ExampleMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value="delegate")}

我完全按照 MapStruct documentation 来装饰我的映射器,这就是为什么我对设置不起作用的原因感到困惑。

@Mapper(componentModel = "spring",
        uses = GenericMapper.class,
        injectionStrategy = InjectionStrategy.CONSTRUCTOR)
@DecoratedWith(ExampleMapperDecorator.class)
public interface ExampleMapper {

    ...

}


public abstract class ExampleMapperDecorator implements ExampleMapper {

    @Autowired
    @Qualifier("delegate")
    private ExampleMapper delegate;

    ...

}

这是我的测试设置,它适用于除装饰映射器之外的所有映射器:

@SpringBootTest(classes = {
        ExampleMapperImpl.class,
        GenericMapperImpl.class
})
class ExampleMapperTest {

    @Autowired
    private ExampleMapper underTest;

    ...

}

如果有人能指出我无法加载 ApplicationContext 的正确方向以及如何修复设置,我将不胜感激。生成的实现如下所示:

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2021-05-26T15:44:17+0200",
    comments = "version: 1.4.2.Final, compiler: javac, environment: Java 13.0.2 (Oracle Corporation)"
)
@Component
@Primary
public class ExampleMapperImpl extends ExampleMapperDecorator implements OrderingMapper {

    private final ExampleMapper delegate;

    @Autowired
    public ExampleMapperImpl(@Qualifier("delegate") ExampleMapper delegate) {

        this.delegate = delegate;
    }

    ...
}

我终于设法解决了这个问题。对于修饰映射器,除了 ExampleMapperImpl 之外,还会生成一个额外的 class ExampleMapperImpl_,它也必须包含在 SpringBootTest 注释中。

@SpringBootTest(classes = {
        ExampleMapperImpl.class,
        ExampleMapperImpl_.class,
        GenericMapperImpl.class
})