Lombok @Accessors(fluent=true)与MapStruct结合使用问题咨询
解决MapStruct无法识别Fluent风格POJO属性的问题
这个问题我之前处理过,fluent模式(没有get/set前缀,直接用属性名作为方法名)的POJO确实会绕开MapStruct默认的Bean规范探测逻辑,不过有几个实用的解决方案,根据你的场景选就行:
方案1:手动指定属性映射(适合属性较少的场景)
直接在@Mapping注解里用expression调用下游POJO的fluent方法,明确告诉MapStruct怎么获取属性值:
@Mapper public interface PojoMapper { PojoMapper INSTANCE = Mappers.getMapper(PojoMapper.class); @Mapping(target = "username", expression = "java(downstreamPojo.username())") @Mapping(target = "email", expression = "java(downstreamPojo.email())") @Mapping(target = "age", expression = "java(downstreamPojo.age())") PojoB convertToPojoB(DownstreamPojo downstreamPojo); }
这种方式简单直接,不用额外配置,但如果POJO属性很多的话,写起来会比较繁琐。
方案2:自定义Accessor命名策略(适合属性较多的场景)
MapStruct允许我们扩展AccessorNamingStrategy来定义自己的属性识别规则,让它能识别fluent风格的getter方法:
第一步:实现自定义命名策略
public class FluentAccessorStrategy extends DefaultAccessorNamingStrategy { @Override public boolean isGetterMethod(ExecutableElement method) { // 识别fluent风格的getter:无参数、方法名与属性名一致、返回当前类类型 if (method.getParameters().isEmpty() && !method.getSimpleName().startsWith("get") && !method.getSimpleName().startsWith("is")) { TypeElement declaringClass = (TypeElement) method.getEnclosingElement(); return method.getReturnType().toString().equals(declaringClass.getQualifiedName().toString()); } // 保留默认的get/is开头的getter识别逻辑,兼容混合模式的POJO return super.isGetterMethod(method); } }
第二步:在Mapper中配置使用该策略
// 先定义一个配置接口 @MapperConfig(accessorNamingStrategy = FluentAccessorStrategy.class) public interface FluentMapperConfig {} // 然后在你的Mapper上引用这个配置 @Mapper(config = FluentMapperConfig.class) public interface PojoMapper { PojoMapper INSTANCE = Mappers.getMapper(PojoMapper.class); // 现在可以直接写映射方法,MapStruct会自动识别fluent方法 PojoB convertToPojoB(DownstreamPojo downstreamPojo); }
这个方案一劳永逸,配置一次后所有同类型的映射都能自动识别fluent属性,非常适合属性多的场景。而且上面的实现还兼容了标准的get/is开头的getter,不用担心影响其他正常POJO的映射。
注意事项
- 自定义命名策略时,要确保逻辑严谨,避免把POJO中其他无参数方法误识别为getter(比如一些工具方法)。上面的实现通过判断返回类型为当前类来过滤,基本能覆盖大部分fluent模式的场景。
- 如果下游POJO的fluent方法返回的不是当前类(比如返回父类),可以稍微调整
isGetterMethod里的返回类型判断逻辑,比如用isAssignableFrom来替代直接相等。
内容的提问来源于stack exchange,提问作者Crosk Cool
相关产品推荐
相关产品推荐

