You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Gradle多模块项目中使用Groovy Abstract Syntax Tree(AST)

Gradle多模块项目中Groovy AST注解生效的完整实现方案

一、项目结构规划

先搭建清晰的多模块结构,把AST转换逻辑和业务代码分离:

root-project/
├── ast-transform/       # AST转换模块(注解定义+转换逻辑)
│   ├── src/main/groovy/
│   │   ├── com/example/ast/MyASTTransformation.groovy
│   │   └── com/example/annotations/MyAnnotation.groovy
│   ├── src/main/resources/
│   │   └── META-INF/services/org.codehaus.groovy.transform.ASTTransformation
│   └── build.gradle
├── app-module/          # 业务模块(使用自定义注解)
│   ├── src/main/groovy/
│   │   └── com/example/app/MyService.groovy
│   └── build.gradle
└── settings.gradle

二、AST转换模块配置与实现

1. 模块构建脚本(ast-transform/build.gradle)

配置Groovy和Java库插件,确保依赖和资源文件正确打包:

plugins {
    id 'groovy'
    id 'java-library'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.codehaus.groovy:groovy-all:3.0.17' // 版本需匹配你的Gradle版本
}

sourceSets {
    main {
        resources {
            srcDirs = ['src/main/resources']
        }
    }
}

2. 自定义注解(MyAnnotation.groovy)

定义编译期生效的注解:

package com.example.annotations

import java.lang.annotation.ElementType
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
import java.lang.annotation.Target

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
@interface MyAnnotation {
    String value() default "default"
}

3. AST转换逻辑(MyASTTransformation.groovy)

实现AST转换接口,给标注注解的方法插入前置逻辑:

package com.example.ast

import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.ast.MethodNode
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.transform.ASTTransformation
import org.codehaus.groovy.transform.GroovyASTTransformation

@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
class MyASTTransformation implements ASTTransformation {

    @Override
    void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
        // 校验输入节点有效性
        if (nodes.length < 2 || !(nodes[0] instanceof MethodNode)) {
            return
        }

        MethodNode targetMethod = (MethodNode) nodes[0]
        // 插入打印语句到方法开头
        def printStmt = new org.codehaus.groovy.ast.stmt.ExpressionStatement(
            new org.codehaus.groovy.ast.expr.MethodCallExpression(
                new org.codehaus.groovy.ast.expr.VariableExpression("this"),
                new org.codehaus.groovy.ast.expr.ConstantExpression("println"),
                new org.codehaus.groovy.ast.expr.ArgumentListExpression(
                    new org.codehaus.groovy.ast.expr.ConstantExpression("AST注入逻辑执行: " + targetMethod.name)
                )
            )
        )
        targetMethod.code.statements.add(0, printStmt)
    }
}

4. 注册AST转换类

在ast-transform/src/main/resources/META-INF/services/下创建文件org.codehaus.groovy.transform.ASTTransformation,内容为转换类的全限定名:

com.example.ast.MyASTTransformation

三、业务模块配置与使用

1. 模块构建脚本(app-module/build.gradle)

关键是确保Groovy编译时能访问到AST转换模块的字节码和配置:

plugins {
    id 'groovy'
    id 'application'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation project(':ast-transform')
    implementation 'org.codehaus.groovy:groovy-all:3.0.17'
}

application {
    mainClass = 'com.example.app.MyService'
}

// 核心配置:让Groovy编译任务包含AST模块的输出
tasks.withType(GroovyCompile) {
    classpath += project(':ast-transform').sourceSets.main.output
}

2. 业务代码中使用注解(MyService.groovy)

package com.example.app

import com.example.annotations.MyAnnotation

class MyService {

    @MyAnnotation
    void executeBusiness() {
        println("业务逻辑执行")
    }

    static void main(String[] args) {
        new MyService().executeBusiness()
    }
}

四、验证运行

在根项目目录执行命令:

./gradlew app-module:run

预期输出:

AST注入逻辑执行: executeBusiness
业务逻辑执行

注意事项

  • 版本兼容:Groovy版本必须与Gradle版本匹配(如Gradle 7.x对应Groovy 3.x,Gradle 8.x对应Groovy 4.x)
  • 编译时依赖:业务模块必须在编译阶段就能访问AST转换模块,不能仅设置runtime依赖
  • 资源打包:AST模块的META-INF配置文件必须被正确打包到输出jar中,否则Groovy无法识别转换类

内容的提问来源于stack exchange,提问作者Derrops

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 22:35:27