• 编译期间生成代码(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.sungroupId>
                <artifactId>toolsartifactId>
                <version>1.8version>
                <scope>systemscope>
                <systemPath>${java.home}/../lib/tools.jarsystemPath>
            dependency>
        dependencies>
        
        <build>
            <pluginManagement>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.pluginsgroupId>
                        <artifactId>maven-compiler-pluginartifactId>
                        <configuration>
                            <source>1.8source>
                            <target>1.8target>
                        configuration>
                        <executions>
                            <execution>
                                <id>default-compileid>
                                <configuration>
                                    <compilerArgument>-proc:nonecompilerArgument>
                                configuration>
                            execution>
                            <execution>
                                <id>compile-projectid>
                                <phase>compilephase>
                                <goals>
                                    <goal>compilegoal>
                                goals>
                            execution>
                        executions>
                    plugin>
    
                plugins>
    
            pluginManagement>
    
        build>
    

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

    当前缺陷

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

    解决

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

  • 相关阅读:
    猿创征文 | 【STM32】ESP8266 wifi模块创建阿里云产品
    Linux system函数返回值
    Java中的分布式计算框架有哪些?
    JAVA深化篇_42—— 正则表达式
    2023年09月青少年软件编程C语言二级真题答案——持续更新.....
    SpringMvc请求流程源码解析
    爱剪辑如何将视频旋转90度,详细操作流程
    携程apollo linux服务器安装部署及问题记录
    如何用CRM软件系统提升销售成绩
    《Docker 简易速速上手小册》第10章 朝着 Docker Swarm 和 Kubernetes 迈进(2024 最新版)
  • 原文地址:https://blog.csdn.net/f_h_h/article/details/139754569