编译期间生成代码(Lombok原理)

通过在编译期间,修改Java的AST(Abstract Syntax Tree)树,可以往类中,添加/修改(覆盖)方法、属性等。

现在比较常见的三方依赖例子有:Lobbok的@Data可以生成get、set方法,@Sl4j2可以生成静态常量log。

这篇文章,主要通过代码展示如何生成get、set方法。

编写一个只在编译期存在的注解:

import java.lang.*;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface Data {    
    
}

注解增强器

Java 编译器对注解的操作,是通过继承AbstractProcessor来实现的。如下是一个添加setter方法:

流程:

  1. 初始化参数操作,见init方法
  2. 在process方法中。生成方法。
  3. 先获取注解元素集合:
  4. 将注解元素转成class定义元素集合:
  5. 最后遍历class元素集合,获取其属性,并生成方法,修改dsfs树。

过程代码涉及信息泄密,忽略。

配置注解增强器

遵循SPI(Service Provider interface),在resources/META-INF/services中配置注解增强器,项目结构结构如下:
先忽略

文件的内容如下,如果有多个增强器,按行配置即可:

incremental.annotation.processors:

com.huawei.fbb.cool.aspect.cool.data.DataProcessor,isolating1

javax.annotation.processing.Processor:

com.huawei.fbb.cool.aspect.cool.data.DataProcessor

效果

参考@Data编译后的class文件

补充说明

由于是编译时注解,注解增强器,一定要单独一个项目(项目A),然后打包给其它服务引用(项目B)。

项目A的pom:

    <dependencies>
        <dependency>
            <groupId>com.sun</groupId>
            <artifactId>tools</artifactId>
            <version>1.8</version>
            <scope>system</scope>
            <systemPath>${java.home}/../lib/tools.jar</systemPath>
        </dependency>
    </dependencies>
    
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                    <executions>
                        <execution>
                            <id>default-compile</id>
                            <configuration>
                                <compilerArgument>-proc:none</compilerArgument>
                            </configuration>
                        </execution>
                        <execution>
                            <id>compile-project</id>
                            <phase>compile</phase>
                            <goals>
                                <goal>compile</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

            </plugins>

        </pluginManagement>

    </build>

其中关于配置,可以用谷歌的 AutoService

当前缺陷

由于往AST插入方法元素,没有判断是否依据存在此类方法,所以很可能覆盖掉之前类中已经存在的方法

解决

增加方法之前,最好先判断一下是否已经含有这个的方法,如果有,就不插入。

相关推荐

  1. 编译期间生成代码Lombok原理

    2024-06-17 22:58:01       9 阅读
  2. lombok

    2024-06-17 22:58:01       12 阅读
  3. 消除代码冗长神器 - Lombok | 入门

    2024-06-17 22:58:01       34 阅读
  4. 【图像生成】(四) Diffusion原理 & pytorch代码实例

    2024-06-17 22:58:01       20 阅读
  5. 代码编译出错可能的原因

    2024-06-17 22:58:01       65 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-17 22:58:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-17 22:58:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-17 22:58:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-17 22:58:01       18 阅读

热门阅读

  1. 一个C++版本的web服务器

    2024-06-17 22:58:01       7 阅读
  2. C++语法14 双分支结构 if…else语句和逻辑运算符

    2024-06-17 22:58:01       5 阅读
  3. Selenium WebDriver - 其它

    2024-06-17 22:58:01       8 阅读
  4. uthash使用指南

    2024-06-17 22:58:01       7 阅读
  5. 深度学习中的热力图

    2024-06-17 22:58:01       5 阅读
  6. selenium常见难点解决方案

    2024-06-17 22:58:01       5 阅读
  7. c++ 矩阵应用

    2024-06-17 22:58:01       5 阅读
  8. 前端开发之浏览器垃圾回收机制

    2024-06-17 22:58:01       4 阅读
  9. LeetCode 3186 最大施法伤害

    2024-06-17 22:58:01       8 阅读
  10. nginx脚本原理(复杂变量)详解

    2024-06-17 22:58:01       7 阅读
  11. c# 根据空格分割字符串

    2024-06-17 22:58:01       8 阅读
  12. 中介子方程二十二

    2024-06-17 22:58:01       4 阅读
  13. 什么是props?

    2024-06-17 22:58:01       5 阅读
  14. 计算机网络期末复习

    2024-06-17 22:58:01       6 阅读