GitHub - houbb/lombok-ex: Java compile time annotation, lombok extension framework.(java 编译时注解框架,对 lombok 进行扩展) (original) (raw)

ENGLISH README

lombok-ex 是一款类似于 lombok 的编译时注解框架。

主要补充一些 lombok 没有实现,且自己会用到的常见工具。

编译时注解性能无任何损失,一个注解搞定一切,无三方依赖。

实现原理:编译时注解 + 编译原理 AST

Maven Central Build Status Coverage Status

创作目的

特性

变更日志

变更日志

快速开始

准备工作

jdk1.7+

maven 3.x+

如 idea 启用编译时注解,勾选【enable annotation process】

maven 引入

com.github.houbb lombok-ex 0.1.0 provided
compile group: 'com.github.houbb', name: 'lombok-ex', version: '0.0.9'

Serial

我们定义一个简单的 pojo,使用 @Serial

package com.github.houbb.lombok.test.model;

import com.github.houbb.lombok.ex.annotation.Serial;

@Serial public class User {

private String name;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

}

编译

直接使用 maven 命令编译

编译结果

查看对应的 User.class 文件,内容如下:

package com.github.houbb.lombok.test.model;

import java.io.Serializable;

public class User implements Serializable { private static final Long serialVersionUID = 1L; private String name;

public User() {
}

public String getName() {
    return this.name;
}

public void setName(String name) {
    this.name = name;
}

}

Util

注解使用

@Util public class StringUtil {

public static boolean isEmpty(final String string) {
    return null == string || "".equals(string);
}

}

效果

public final class StringUtil { private StringUtil() { }

public static boolean isEmpty(String string) {
    return null == string || "".equals(string);
}

}

ToString

简介

@ToString 注解在类上使用,可以默认生成 toString() 方法

例子:

import com.github.houbb.lombok.ex.annotation.ToString;

@ToString public class ToStringTest { }

效果

编译后的 class 文件信息:

ps: 此处依赖 FastJSON,请自行引入。

import com.alibaba.fastjson.JSON;

public class ToStringTest { public ToStringTest() { }

public String toString() {
    return JSON.toJSONString(this);
}

}

指定方式

@ToString 可以指定生成的方式,默认是 FastJson,目前还支持基于字符串拼接的方式:

源码

@ToString(ToStringType.CONCAT) public class ToStringConcatTest {

private String name;

private int age;

private int[] ints;

}

效果

import java.util.Arrays;

public class ToStringConcatTest { private String name; private int age; private int[] ints;

public ToStringConcatTest() {
}

public String toString() {
    return "ToStringConcatTest{name=" + this.name + ", age=" + this.age + ", ints=" + Arrays.toString(this.ints) + "}";
}

}

Sync

使用

直接指定在方法上。

@Sync public void syncTest() { System.out.println("sync"); }

效果

public synchronized void syncTest() { System.out.println("sync"); }

Modifiers

说明

@Modifiers 可修改类、方法、字段的访问级别。

暂时可能没有特别好的应用场景,取决于用户自己的使用。

注意:不要搞一些难以理解的东西,尽可能便于使用者理解。

使用方式

@Modifiers 还有一个 appendMode 属性,默认为 true。

如果设置为 false,可以直接将修饰符改为用户指定的。

import com.github.houbb.lombok.ex.annotation.Modifiers; import com.github.houbb.lombok.ex.constant.Flags;

@Modifiers(Flags.FINAL) public class ModifiersTest {

@Modifiers(Flags.VOLATILE)
private int value;

@Modifiers(Flags.SYNCHRONIZED)
public static void syncTest() {
    System.out.println("sync");
}

}

效果

public final class ModifiersTest { private volatile int value;

public ModifiersTest() {
}

public static synchronized void syncTest() {
    System.out.println("sync");
}

}

UnsupportedOperation

说明

@UnsupportedOperation 可以放在方法、构造器上,用于说明当前方法不支持。

等价于 throw new UnsupportedOperationException();

使用

@UnsupportedOperation public static void add() { }

效果

public static void add() { ExceptionUtil.throwException(UnsupportedOperationException.class); }

SPIAuto

说明

该注解配合 SPI 应用使用。

代码使用

@SPIAuto("good") public class SayGood implements Say{

@Override
public void say() {
    System.out.println("good");
}

}

@SPIAuto("bad") public class SayBad implements Say{ @Override public void say() { System.out.println("bad"); } }

效果

编译后在对应目录下生成文件 com.github.houbb.lombok.ex.test.spi.Say

内容如下:

good=com.github.houbb.lombok.ex.test.spi.SayGood
bad=com.github.houbb.lombok.ex.test.spi.SayBad

效果

Benchmark

此处以 @ToString 为例,其他条件保持一致。进行 10W 次输出耗时统计。

Benchmark

可见编译时注解和原生写法耗时一致(原理是一样的),优于 FastJSON 基于运行时注解的实现。

后期 Road-map

思路:通过 AST 直接解析文本,然后通过 AST 结合 jdk utils 重新构建 class 文件。