2KB项目,专业的源码交易网站 帮助 收藏 每日签到

使用 Lombok 减少你的样板代码

  • 时间:2019-01-23 18:49 编辑:2KB 来源:2KB.COM 阅读:493
  • 扫一扫,手机访问
  • 分享
摘要:
Lombok 英文原文:Lombok Reduces Your Boilerplate Code

这篇文章里,我会为你展示这周我偶尔遇到的一个强大的产品: Lombok项目 允许你修改编译好的字节码。首先,我会详细描述下Lombok的特征,让你有初步的了解。在这篇文章的第二部分,我会描述怎样去扩展它来生成你的代码。

介绍

自从JEE开始就有一些抱怨组件编码的复杂性。我认为EJB v2就是这复杂性的好例子:只是一个简单的EJB,你不得不为EJB类提供一个home和每种方位类型的接口(本地和远程)。这就使它变得复杂,容易犯错以及更重要的是让你没多少时间去关注正在值得去关注的业务代码。两个举措表名了在编码时减少需要样板代码数量的愿望:

  • Spring Framework的格言就是减少JEE的复杂度。样板代码只在Spring框架里编写一次同时只由项目来使用。
  • EJB v3已经从Spring学到了不少东西,也致力于减少样板代码,让本地和远程接口变得不再必要。最后,下一个版本的规范也会让本地和远程home变为可选。

Lombok项目的目的同上面两个举措差不多,但为了这么做,它使用另外的途径。

注解处理

Java的第五个版本介绍了注解的概念,代码元数据可以在编译时或运行时处理。不幸的是,在JDK5里,编译时注解分成了两个步骤。首先,你必须运行apt可执行文件处理注解,可以是创建或修改源文件,然后使用javac编译你的源代码。这不是最好的方法,所以在Java6移除了apt同时让javac能够管理注解,让处理注解能顺畅地在简单的一步计算完成。这也是Lombok采用的途径。

Lombok项目

Lombok核心特征是你需要用注解来创建代码,目的是减少你要写的样板代码的数量。它为你提供如下注解,这可能会永远改变代码(不是你的生活):

例如,当你学习OO(面向对象)方式来编码,你经常是把你的字段设置为私有同时编写公共的访问器来访问这些字段:

public class Person {

  private String name;

  public String getName() {

    return name;
  }

  public void setName(String name) {

    this.name = name;
  }
} 

因为这种写法是很烦人的,一些(并非全部)IDE会有一个功能来生成访问器。它有一些缺点:

  • 如果你移除一个字段,相应地你要手动移除访问器。
  • 它会把你的真实代码和样板代码弄得混乱
  • 结果:要花费精力在一个长的类里去检查这个字段是不是已经有访问器存在了

此外,手动创建访问器是比较容易出错的:有一次,我花费几个小时在同事写的代码里找一个bug,最后发现是setter写错了。

因为getter/setter仅仅是字段的元数据,Lombok的立场就是把这些方法看成这样:Java里的元数据都通过注解来管理。看下面的代码:

import org.lombok.Getter;
import org.lombok.Setter;

public class Person {

  @Getter @Setter
  private String name;
}

我反编译了生成的class文件(使用 JAD),发现它其实创建的字节码都是完全相同的,只是源代码更为简洁和更不容易产生错误。

思考一下,我发现有3个对使用Lombok的争论:

  1. 第一个争论是使用这种策略会导致你不能创建一个类似于protected的访问器。你错了,Lombok是可以配置的:

    import lombok.AccessLevel;
    import org.lombok.Getter;
    import org.lombok.Setter;
    
    public class Person {
    
      @Getter @Setter(AccessLevel.PROTECTED)
      private String name;
    }

    同时这对所有提供的注解都有效。可以去阅读一下

  2. 第二个争论是使用Lombok会让你不知道它在实际的背后做了什么。这是对的,但是这同样也可以这样说你在用的AOP、CGLIB等框架。
  3. 最后的 争论,恕我直言,这是唯一有效的争论,它会让调试更加复杂:但同样,Spring在它的整个项目代码里都使用了Java的动态代理,而且仍然有很多项目在使用。

使用和安装

使用Lombok有3个步骤操作:

  1. 把包放到类路径(classpath)
  2. 在你想用的地方加入注解
  3. 使用javac编译

虽然,这里有一个问题。注意下最后那句对javac的强调。由于大部分(并非全部)你和我都知道的开发者专注于一点效率,导致大家都去使用IDE。我不知道NetBeans和其他同类的IDE(是否有问题),但是我喜欢用的Eclipse不会使用javac来编译而是它内置的编译器。

我们来自Lombok的朋友也想到了这点,同时Lombok也能够hook到Eclipse的编译过程中。为了要做到这个,只要执行lombok.jar然后你在你屏幕上看到下面的说明:它将会加入两行东西到你的eclipse.ini里。

一个忠告(因为我犯了这个错误):如果你通过有参数的命令行来启动Eclipse,例如是Window的快捷方式,这些参数是会优先使用,同时eclipse.ini会默默地忽略掉了。这只是让你知道一下...

Lombok扩展

据我了解, 目前只有一款名为Morbok的Lombok扩展。它让你只使用注解来创建典型的私有静态常量logger。

好处是Morbok使用全限定类名作为logger的名字,这样就不会再有复制错误了。坏处是如果你不使用Commons Logging作为你的日志框架,你必需为每个@Logger注解配置你要使用的框架,这里是没有全局配置的:依我看来,下个版本可能会修复这个问题(有这个版本?)。

架构

先说重要的,Lombok需要JDK6来编译,因为注解处理是在Java5的APT完成的。现在,Lombok在环境已经为类构建了AST后直接hook到编译过程中。

然后传递结构从而形成它每个引用的处理程序。每个注解都有一个处理程序:@Getter的HandleGetter,@Setter的HandlerSetter等待。处理程序的责任是处理注解,你可以猜想下它是什么。

扩展Lombok

扩展Lombok分为3个步骤:

  1. 创建注解。因为注解是在编译时使用的,它能在以后安全地丢弃而它的保留策略会由它的默认值决定(名为RetentionPolicy.SOURCE)
  2. 创建处理器. 处理器是直接实现lombok.javac.JavacAnnotationHandler<T extends Annotation>的类。为什么是直接地? 因为Lombok使用ServiceProvier服务,这是它的一个限制。
  3. 在META-INF/services下一个名为lombok.javac.JavacAnnotationHandler的文件里引用吹利器的全限定类名。

真正在编码是在步骤2里:接口有一个单独的方法handle(AnnotationValues<T> annotation,com.sun.tools.javac.tree.JCTree.JCAnnotation ast, JavacNode annotationNode).注意到第二个参数的包了吗?它表示Sun的私有实现。它有一些大缺点:

  • 文档非常稀少,即使不是完全不可用。在这里,你会陷入一个位置的领域
  • 因为com.sun.tools.javac不是公共API的一部分,它可能随时改变。你可能每次更新后都弄坏你的代码
  • 记得之前我说过这是只适合Java的(javac编译和Eclipse编译)?现在还成立的。如果你想这个新的注解在Eclipse下工作,你要编写额外的处理器

例子

我编写了一个使用@Delegate注解的雏形作为例子。这样一个在字段的注解表示声明的类会和字段的类有相同的公共方法,同时每个方法的主体会调用委托对象的方法。

public class Delegator {

  @Delegate
  private DelegateObject object;

  ...
}

public class DelegateObject {

  public void doSomething() {
    ...
  }
}

上面的代码会生成和下面代码相同的字节码:

public class Delegator {

  private DelegateObject object;

  public void doSomething() {

    object.doSomething();
  }
  ...
}

到目前为止:

  • 它不处理泛型
  • 只为javac提供了处理器
  • 它不能配置

最终的实现交给勇敢的阅读者们来完成:原始代码在这里是用Eclipse/Maven的格式。

结语

一些改进将很快加入到Lombok里。首先,我不喜欢JAR的整体结构。恕我直言,它可以很好地解耦到3个独立的JAR包:Lombok本身,提供注解和关联的处理器,以及最后还有安装器。

此外,为每个注解编写两个处理器是很费时的。更何况你也想支持NetBeans呢?也许使用Service Provider就是个错误...

最后,依赖于Sun的内部编译API是很大的风险。我任务如果Lombok能提供一个对这API的facade,它能减少企业使用这个工具的风险,同时桥接代码能够交给懂得这个API的人(Lombok队伍)而不是开发者(像我这样的)。

总而言之,不关这些缺陷,Lombok通过很好模仿Spring的成功做法,让它看起来是个非常有前途的项目。这是我无论如何都期待它的原因,因为它的小思维带来了如此大的价值:一路走好!

了解更多:

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。 2KB翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。


2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务

  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【计算机/互联网|】Nginx出现502错误(2020-01-20 21:02)
【计算机/互联网|】网站运营全智能软手V0.1版发布(2020-01-20 12:16)
【计算机/互联网|】淘宝这是怎么了?(2020-01-19 19:15)
【行业动态|】谷歌关闭小米智能摄像头,因为窃听器显示了陌生人家中的照片(2020-01-15 09:42)
【行业动态|】据报道谷歌新闻终止了数字杂志,退还主动订阅(2020-01-15 09:39)
【行业动态|】康佳将OLED电视带到美国与LG和索尼竞争(2020-01-15 09:38)
【行业动态|】2020年最佳AV接收机(2020-01-15 09:35)
【行业动态|】2020年最佳流媒体设备:Roku,Apple TV,Firebar,Chromecast等(2020-01-15 09:31)
【行业动态|】CES 2020预览:更多的流媒体服务和订阅即将到来(2020-01-08 21:41)
【行业动态|】从埃隆·马斯克到杰夫·贝佐斯,这30位人物定义了2010年代(2020-01-01 15:14)
联系我们

Q Q: 7090832

电话:400-0011-990

邮箱:7090832@qq.com

时间:9:00-23:00

联系客服
商家入住 服务咨询 投拆建议 联系客服
0577-67068160
手机版

扫一扫进手机版
返回顶部