• 编译期间生成代码(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插入方法元素,没有判断是否依据存在此类方法,所以很可能覆盖掉之前类中已经存在的方法

    解决

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

  • 相关阅读:
    随机森林项目实战---气温预测
    python如何操作mysql数据库
    PokéLLMon 源码解析(一)
    Mysql整理-SQL语言
    【工作总结】努力工作为什么感觉没用
    uni-app 的坑
    使用插值方法(scipy.interpolate)和三维数据构造二元函数
    美国fba海运清关基本流程
    ATF(TF-A) fvp_r 平台威胁模型-安全检测与评估
    开发盲盒应该具有哪些特点
  • 原文地址:https://blog.csdn.net/f_h_h/article/details/139754569