
概述Accessors是 Lombok 提供的一个注解用于配置 getter 和 setter 方法的生成方式。它可以控制是否生成链式调用fluent风格的 setter 方法以及是否使用前缀。基本用法importlombok.Data;importlombok.experimental.Accessors;DataAccessors(chaintrue)publicclassUser{privateStringname;privateIntegerage;privateStringemail;}主要属性1. chain链式调用默认值false当设置为true时setter 方法返回this而不是void支持链式调用。示例对比不使用 chain默认DatapublicclassUser{privateStringname;privateIntegerage;}// 使用方式UserusernewUser();user.setName(张三);user.setAge(25);使用 chain trueDataAccessors(chaintrue)publicclassUser{privateStringname;privateIntegerage;}// 使用方式 - 支持链式调用UserusernewUser().setName(张三).setAge(25);2. fluent流式风格默认值false当设置为true时生成的 getter 和 setter 方法不带get/set前缀直接使用字段名作为方法名。示例对比不使用 fluent默认DatapublicclassUser{privateStringname;}// 使用方式UserusernewUser();user.getName();user.setName(张三);使用 fluent trueDataAccessors(fluenttrue)publicclassUser{privateStringname;}// 使用方式 - 方法名就是字段名UserusernewUser();user.name();// 相当于 getName()user.name(张三);// 相当于 setName(张三)注意fluent true时chain 默认为true所以自动支持链式调用。3. prefix前缀默认值{}空数组指定字段的前缀Lombok 会在生成 getter/setter 时去除这些前缀。示例DataAccessors(prefixm)publicclassUser{privateStringmName;privateIntegermAge;}// 生成的方法user.getName();// 去除了 m 前缀user.getAge();// 去除了 m 前缀user.setName(张三);user.setAge(25);多个前缀DataAccessors(prefix{m,_})publicclassUser{privateStringmName;privateString_email;}// 生成的方法user.getName();user.getEmail();组合使用chain fluentDataAccessors(chaintrue,fluenttrue)publicclassUser{privateStringname;privateIntegerage;}// 使用方式UserusernewUser().name(张三).age(25);// 获取值Stringnameuser.name();Integerageuser.age();chain prefixDataAccessors(chaintrue,prefixm)publicclassUser{privateStringmName;privateIntegermAge;}// 使用方式UserusernewUser().setName(张三).setAge(25);三者组合DataAccessors(chaintrue,fluenttrue,prefixm)publicclassUser{privateStringmName;privateIntegermAge;}// 使用方式UserusernewUser().name(张三).age(25);实际应用场景1. Builder 模式替代对于简单的 DTO 对象可以使用Accessors(chain true)实现类似 Builder 的效果DataAccessors(chaintrue)publicclassCreateUserRequest{privateStringusername;privateStringpassword;privateStringemail;privateIntegerage;}// 使用CreateUserRequestrequestnewCreateUserRequest().setUsername(zhangsan).setPassword(123456).setEmail(zhangsanexample.com).setAge(25);2. 领域对象在领域驱动设计DDD中使用 fluent 风格可以让代码更易读DataAccessors(fluenttrue)publicclassOrder{privateStringorderId;privateBigDecimalamount;privateLocalDateTimecreateTime;}// 使用OrderordernewOrder();order.orderId(ORD001);order.amount(newBigDecimal(100.00));3. 与第三方框架集成某些框架如 MyBatis、JPA要求标准的 JavaBean 规范带 get/set 前缀此时不应使用fluent true// ✅ 推荐保持标准 JavaBean 规范DataAccessors(chaintrue)publicclassUserDO{privateLongid;privateStringname;}// ❌ 不推荐可能与其他框架不兼容DataAccessors(fluenttrue)publicclassUserDO{privateLongid;privateStringname;}注意事项1. 兼容性JSON 序列化Jackson、FastJSON 等库默认识别标准的getXxx()/setXxx()方法。使用fluent true可能导致序列化问题。ORM 框架Hibernate、MyBatis 等通常要求标准的 JavaBean 规范。Spring FrameworkSpring 的数据绑定依赖标准的 getter/setter。2. Boolean 类型对于boolean类型的字段getter 方法会生成isXxx()而不是getXxx()DataAccessors(chaintrue)publicclassUser{privatebooleanactive;}// 生成的方法user.isActive();// getteruser.setActive(true);// setter返回 this3. 与 Builder 的关系如果已经使用了Builder通常不需要Accessors(chain true)DataBuilderpublicclassUser{privateStringname;privateIntegerage;}// 使用 BuilderUseruserUser.builder().name(张三).age(25).build();4. 继承场景父类和子类的Accessors配置不会互相影响DataAccessors(chaintrue)publicclassBaseUser{privateStringid;}DataAccessors(chainfalse)// 子类可以有不同的配置publicclassAdminUserextendsBaseUser{privateStringrole;}最佳实践✅ 推荐做法DTO/VO 对象使用 chain trueDataAccessors(chaintrue)publicclassUserDTO{privateStringname;privateIntegerage;}实体类保持标准规范DataEntitypublicclassUser{IdprivateLongid;privateStringname;}内部类或工具类可以使用 fluentDataAccessors(fluenttrue)publicstaticclassConfig{privateStringhost;privateIntegerport;}❌ 避免的做法不要在持久化实体上使用 fluent// ❌ 不推荐EntityDataAccessors(fluenttrue)publicclassUser{privateLongid;}不要混用不同的访问器风格// ❌ 不推荐团队内应统一风格DataAccessors(chaintrue)publicclassUser{...}DatapublicclassOrder{...}// 没有 chainprefix 不要过度使用// ❌ 不推荐前缀过多会导致混乱Accessors(prefix{m,_,field})性能影响Accessors只是在编译时生成不同的方法签名对运行时性能没有影响。选择哪种风格主要取决于代码可读性团队规范框架兼容性总结属性默认值作用适用场景chainfalsesetter 返回 thisDTO、VO、需要链式调用的场景fluentfalse去除 get/set 前缀内部类、配置类、追求简洁的场景prefix{}去除字段前缀遗留代码、特定命名规范核心原则优先保证框架兼容性保持团队代码风格一致根据具体场景选择合适的配置