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

如何配置多模块Gradle Java项目实现公开API对接私有核心代码

问题根因

你当前的循环依赖完全是依赖方向倒置导致的,同时你列出的第2条需求存在本质的架构设计偏差:

API模块编译阶段需支持引用Core以完成API构建

这个思路完全违反插件架构的依赖倒置原则,参考你提到的PaperMC、Jenkins实现,对外公开的API是纯契约层,永远不能反向依赖作为私有实现的Core。PaperMC的API模块全是接口、模型、注解、事件定义这类无具体逻辑的契约,根本看不到任何核心服务端实现代码,Core作为实现方单向依赖API完成逻辑,不存在反向依赖的场景。

修正后的分层架构

整个项目只需要保留两个模块即可,完全满足你的所有要求:

  • API 模块:公共契约层,是唯一对外发布给第三方插件开发者的产物,内部只定义插件开发所需的接口、数据模型、自定义注解、插件生命周期规范、事件总线抽象,不包含任何业务实现,零Core依赖
  • Core 模块:私有核心实现层,所有不对外暴露的业务逻辑、插件加载器实现、API接口的具体实现都放在这个模块,该模块的编译产物永远不对外公开

需求匹配验证

  • Core代码完全不对外公开:对外仅发布API模块的jar,第三方开发者无法获取任何Core模块的类
  • API产物不含Core代码:API完全不依赖Core,编译、运行阶段都不会引入Core的任何类,不存在代码泄漏
  • Core可访问所有API能力:Core单向依赖API,符合依赖方向,所有API定义的契约都可以在Core中实现
  • Core内置API:打包时将API的class文件打入Core的最终jar,运行时可直接识别第三方插件对API的调用,完成插件加载
Gradle配置方案

首先确保根目录settings.gradle正确引入两个模块:

rootProject.name = 'your-project-name'
include 'API'
include 'Core'

API模块build.gradle配置

完全移除对Core的依赖,只保留公共开发所需的依赖项:

plugins {
    id 'java'
    id 'maven-publish' // 用于发布API产物给第三方开发者
}

group = 'com.awesomedude'
version = '1.0.0-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    // 仅保留插件开发需要的公共依赖,私有依赖全部放到Core模块
    implementation 'org.jetbrains:annotations:22.0.0'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}

test {
    useJUnitPlatform()
}

// 配置API发布规则,仅发布该模块到公共/私有Maven仓库
publishing {
    publications {
        maven(MavenPublication) {
            from components.java
            artifactId = 'your-project-api'
        }
    }
}

Core模块build.gradle配置

单向依赖API模块,配置打包规则将API内置到Core产物中:

plugins {
    id 'java'
}

group = 'com.awesomedude'
version = '1.0.0-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    // 单向依赖API,编译、运行阶段均可见
    implementation project(':API')
    // 以下为Core私有依赖,不会泄漏到API层
    implementation 'commons-io:commons-io:2.11.0'
    implementation 'org.jetbrains:annotations:22.0.0'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}

test {
    useJUnitPlatform()
}

// 打包配置:将API模块及所有运行时依赖打入Core的最终jar,实现内置API
jar {
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    from {
        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }
    manifest {
        attributes 'Main-Class': 'com.awesomedude.core.Main' // 替换为你的主类全限定名
    }
}
开发规范提示
  • 所有需要暴露给插件调用的能力,必须先在API模块定义对应公共接口,再到Core模块编写实现类,API层绝对不能出现Core包下的类引用
  • 加载第三方插件时,使用自定义ClassLoader加载插件jar,将插件ClassLoader的父加载器设置为Core主类加载器,通过类加载器隔离保证插件只能访问API层的类,完全无法触达Core的私有实现
  • 如果需要Core向API侧传递实现类实例,通过Java SPI、依赖注入或者事件总线机制实现,不要在API层硬编码引用Core实现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 15:54:31