嘴上说反对Lombok,身体却很诚实…

我见过很多反对 Lombok 的同学 , 背地里又偷偷的把插件添加了进去 , 这是真香原理在搞鬼 。
嘴上说反对Lombok,身体却很诚实…文章插图
图片来自 Pexels
嘴上说不要 , 身体很诚实 。 反对的人 , 应该是没见过一些业务代码的冗长繁杂 , 还沉浸在自己病态的完美主义中 。 要面对又脏又乱的从业环境 , 面对现实 。
Lombok 可以消除 Java 的冗长 , 减少代码的长度 , 让关注点转移到该专注的地方 。
SpringBoot 把 Lombok 放到了它的依赖中 , Java14 甚至也借鉴了这种思想 , 推出了 record 语法 。
就是类似于下面这种:
record Point(int x, int y) { } 本篇文章 , 不打算讨论什么类似于 @Data 注解之类的 。 我们讨论一个比较偏门的 , 但是又让你感觉相见恨晚的一个注解:RequiredArgsConstructor 。
爆炸的属性注入
Spring 提供了两种注入模式 , 这也是非常初级的程序员经常被问到的三种 DI 写法 。
一种是属性注入(Filed injection) , 一种是通过 Setter 方法 , 一种是构造器注入 。
霍霍 , 我撒谎了 , 经常被问的是 byName 和 byType 。 不过 , 这年头 , 我们用的跟多的是 @Autowired 注解 。
代码写起来一般是这样的:
@Service public class GoodsServiceImpl implements GoodsSrv {@Autowiredprivate GoodsRepo goodsRepo;@Autowiredprivate TagRepo tagRepo;@Autowiredprivate TagRefRepo tagRefRepo;@Autowiredprivate BrandRepo brandRepo;@Autowiredprivate UnitRepo unitRepo; } 这一般没什么问题 , 因为注入的字段是有限的 。 但如果你没见过一些项目代码 , 你会被这种程序界完美的表象给蒙骗了 。
业务代码 , 不加注释 , 单文件长度超过 2000 行的比比皆是 。 注入的属性能达到十几个之多 。 这部分注入代码真是脏乱差 。
不仅如此 , 这些字段 , 还会在 IDE 里变成灰色 , 告诉你未被初始化 , 代码变成了丑八怪 。
嘴上说反对Lombok,身体却很诚实…文章插图
事实上 , Spring 从 4.0 开始 ,就 不 推 荐 使 用 属 性 注 入 模 式 了, 原因是它可以让我们忽略掉一些代码可能变坏的隐患 。 你可以自行搜索这个问题 , 我们也不展开说了 。
既然 Spring 推荐使用显示的 Setter 和构造器方式 , 那我们就切换一下实现方案 。
Setter 方法基本上用的人比较少 , 因为它更加臭更加长 。 要是给每一个属性写一个 set 方法 , 我估计你即使用代码生成器也玩吐了 。
构造器注入
那么 , 构造器的方法就成了我们的首选 。
样例代码如下:
public class GoodsServiceImpl implements GoodsSrv {private GoodsRepo goodsRepo;private TagRepo tagRepo;private TagRefRepo tagRefRepo;private BrandRepo brandRepo;private UnitRepo unitRepo;public GoodsServiceImpl(GoodsRepo goodsRepo,TagRepo tagRepo,TagRefRepo tagRefRepo,BrandRepo brandRepo,UnitRepo unitRepo) {this.goodsRepo = goodsRepo;this.tagRefRepo = tagRefRepo;this.tagRefRepo = tagRefRepo;this.brandRepo = brandRepo;this.unitRepo = unitRepo;this.tagRepo = tagRepo;} } Spring 不需要加入其他注解 , 就可以使用构造器完成注入 。 问题是 , 我们依然要写很多代码 。
这个时候 , 你可能想到了 Lombok 的 AllArgsConstructor 注解 。 但它是针对于全部的属性的 , 如果类中有一些非 Bean 的属性 , Spring 就会晕菜 。
这个时候 , 就可以使用 RequiredArgsConstructor 了 。
【嘴上说反对Lombok,身体却很诚实…】代码如下:
@Service @RequiredArgsConstructor public class GoodsServiceImpl implements GoodsSrv {final GoodsRepo goodsRepo;final TagRepo tagRepo;final TagRefRepo tagRefRepo;final BrandRepo brandRepo;final UnitRepo unitRepo; } 我们把需要注入的属性 , 修改成 final 类型的(或者使用 @NotNull 注解 , 不推荐) , 这些属性将构成默认的构造器 。
Java 要求 final 类型的属性必须要初始化 , 如果没有构造方法代码就会变红 。
我们可以看到修改之后的 IDE , 恼人的灰色提示也消失了 。
嘴上说反对Lombok,身体却很诚实…文章插图
这样的代码 , 是非常简洁的 。
更高级一点
RequiredArgsConstructor 注解 , 你还可以像下面这样写 。 即使是把 @__ 换成 @_ , 或者换成 @___ , 也是能正常的运行 。
@RequiredArgsConstructor(onConstructor = @__(@Autowired)) 它的意思是 , 给使用 Lombok 生成的构造器方法 , 加入一个 @Autowired 注解 。
这是彻头彻尾的 Lombok 语法 , 不过现在的 Spring 已经不需要加入这样的注解就能运行了 。