稀土掘金技术社区 2024年12月16日
马上 2025 年了,还在用 Maven 搭建 SpringBoot 项目吗?
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍了用Java开发的日语语言分析工具,着重讲述了用gradle搭建父子项目的过程,包括项目结构、父模块与子模块配置等内容。

🎯项目采用多种技术,如java、kotlin、swing等,并在springboot中运行java swing界面

📄父模块配置依靠build.gradle.kts、settings.gradle.kts,引入各个模块并进行相关设置

📋子模块介绍了创建与引入方法,各子模块有不同功能及相应的依赖配置

💻项目中复杂模块的gradle配置虽复杂但仍较简单,且可直接写kotlin代码并与java互引

原创 CrimsonHu 2024-12-16 08:30 重庆

点击关注公众号,“技术干货” 及时达!

项目介绍

这是我在今年9月研一开学后,选定了研究方向,就顺手用 Java 撸了一个「日语语言分析工具」

除了它本来的功能,它在技术上的特点是如下三条:

    在 springboot 中运行 java swing 界面(下图的界面就是用 swing 实现的)

    使用 gradle 搭建的父子项目,并支持 kotlin 混写

    内置一个 chromium 内核

本文就着重介绍第二点。

主要技术:「java」 + 「kotlin」 + 「swing」 + 「springboot」 + 「gradle」

运行环境:「JetBrains Runtime with JCEF(Java 21)」

「在我看来,每一次项目开发都应该是一次技术的积累,经验的进步。」 所以在这次的项目搭建中,就尝试了「用 gradle 去代替以前 maven 父子项目的方案,同时拥抱下 kotlin」 。为什么会写这篇文章呢?因为在这次项目搭建过程中踩了很多坑。在这个项目中收获最大的就是掌握了基于 「gradle.kts」 的项目搭建。

除此之外,界面是 swing 做的,这也是我的一个强项,用 Java 手搓 GUI 。

「以下是主要界面:」

项目结构

我不喜欢分享很难懂的东西。我尽力将本文内容写得简单,让大家都能看懂,也能够真正有所收获。

直接来看项目结构:

如图,项目结构其实很简单。虽然文件夹很多,但是真正只用关心的是中间的 gradle 子项目模块build.gradle.ktssettings.gradle.kts 这三个地方。

什么?你还不会创建 gradle 项目?其实很简单, Spring Initializr 会帮你创建。如图:

创建项目完成后,就可以将其改造为父子项目了。

父模块配置

父模块配置依靠项目根目录下的 build.gradle.ktssettings.gradle.kts

先看 settings.gradle.kts

rootProject.name = "cable-car"
include(":1-common")include(":1-reactivex")include(":1-spring-application")include(":2-jp-analysis-core")include(":3-client-framework")include(":4-web-jp-learning")

可以很明显地看到,该配置文件中的 include(":xxxxx") 就是将上述项目结构中的各个模块引入到 settings.gradle.kts 中(记得不要忘记冒号)。 rootProject.name 即为项目名。


再来看 build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
group = "com.hu.cablecar"version = "0.0.1"description = "缆车"
// Java 版本java { sourceCompatibility = JavaVersion.VERSION_21 targetCompatibility = JavaVersion.VERSION_21}
// 用于支持 Java 与 kotlin 混写,以及 lombok 依赖引入plugins { java kotlin("jvm") version "1.9.24" kotlin("plugin.lombok") version "1.9.24" id("io.freefair.lombok") version "8.10"}
// 全局配置allprojects {
// 将上述 plugins 应用到子模块 plugins.apply(JavaPlugin::class.java) plugins.apply("kotlin") plugins.apply("kotlin-lombok") plugins.apply("io.freefair.lombok")
// 仓库地址 repositories { maven { url = uri("https://maven.aliyun.com/nexus/content/groups/public/") } mavenCentral() mavenLocal() }
tasks.withType<JavaCompile>() { options.encoding = "UTF-8" }
tasks.withType<Javadoc>() { options.encoding = "UTF-8" }
tasks.withType<KotlinCompile> { kotlinOptions { freeCompilerArgs = listOf("-Xjsr305=strict") jvmTarget = "21" } }}

这就是 build.gradle.kts 需要准备的全部内容,可以很直观地看到,它主要就做了三件事:

    定义了 Java 版本

    引入了 Javakotlinlombok 相关支持,并应用到子项目

    配置了依赖的 maven 下载地址

子模块

接下来就是子模块的介绍,怎么创建子模块,怎么将一个子模块引入到另一个子模块。

1-common:

在上文项目结构中,我们先看最简单的子模块 1-common

这个模块只包含三个 Java 写的工具类,以及一个 build.gradle.kts 配置文件。来看看配置文件的内容:

description = "公共基础模块"
dependencies { implementation("com.alibaba.fastjson2:fastjson2:2.0.45")}

配置文件内容很简单:

现在就能看到为什么要使用 gradle 来搭建项目了。因为相比于 maven , gradle 的配置文件真的很简单。

1-reactivex:

看完最简单的子模块 1-common 后,来看看稍微复杂一点点的 1-reactivex 模块:

这个模块的作用是用 rxJava 实现了一个发布订阅的功能。这里的代码就是一直没时间单独写篇文章的那个“跨组件通信的 Java 版本”(没时间,真没时间...《下次一定》)。我只用RxJS,却搞定了三大框架的跨组件通信,甚至还能适用于Java(一、Angular篇)跨组件通信,远比你想象的要简 - 掘金

Java swing 的跨组件通信我就是用这个方法去做的(所以说功能的实现思路都是相通的。全栈的目的,就在于「不要将自己局限在一个语言甚至一个框架里面」)。

好了,题外话说完,来聊回这个模块的配置。来看 build.gradle.kts 配置文件:

description = "RX"
dependencies { // 像这样的写法,只会引入1-common自己的代码,不会引入它的依赖fastjson2 implementation(project(":1-common")) implementation("io.reactivex.rxjava3:rxjava:3.1.9")}

dependencies 可以看到,这个模块不仅引入了 rxjava ,也引入了子模块 1-common ,因为该模块用到了它里面工具类的一个方法。

2-jp-analysis-core:

同样的,这也是一个工具模块,用来做日语文字解析。代码结构与配置文件如下:

build.gradle.kts

description = "日语分析核心模块"
plugins {}
dependencies { implementation(project(":1-common")) implementation("commons-io:commons-io:2.15.1")}

可以看到,这个模块引入了 commons-io 和子模块 1-common

3-client-framework:

重点来了,这是项目启动的 main 方法所在的模块,也是整个项目的界面。

它很复杂。引入了其它各个子模块,在使用 springboot 启动 swing 界面的同时,也使用了 Javakotlin 混写。

来看看它的配置文件 build.gradle.kts

description = "客户端UI框架"
plugins { // spring相关配置 kotlin("plugin.spring") version "1.9.24" id("org.springframework.boot") version "3.3.4" id("io.spring.dependency-management") version "1.1.6"}
dependencies { // 引入各个子模块 implementation(project(":1-common")) implementation(project(":1-reactivex")) implementation(project(":1-spring-application")) implementation(project(":2-jp-analysis-core")) implementation(project(":4-web-jp-learning")) // 引入maven依赖 // 在上面引入子模块时,不会引入子模块自己的依赖 // 所以如果在此使用了同样的依赖例如这里的commons-io与rxjava,需要在该模块中再次引入 implementation("org.springframework.boot:spring-boot-starter") implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-tomcat") implementation("io.reactivex.rxjava3:rxjava") implementation("commons-io:commons-io:2.15.1") // 引入本地jar依赖 implementation(files("lib/ui/flatlaf-3.5.2.jar")) implementation(files("lib/ui/flatlaf-intellij-themes-3.5.2.jar")) implementation(files("lib/ui/JTattoo-1.6.13.jar"))}
tasks.jar { // 设置gradle任务:打包为jar enabled = true manifest { attributes(mapOf("Main-Class" to "com.hu.cablecar.client.framework.ClientFrameworkApplication")) }}

可以在配置文件中看到:

配置了 task.jar 后,可以在此执行相应的任务,将该模块打包为 jar 。

于是能够看出,即使是复杂的模块,其 gradle 配置依然简单清爽。如果是 mavenpom.xml 配置,那么肯定就不只这么一点代码了。

由于在根目录下的 build.gradle.kts 中配置了 kotlin ,以及在该模块也进行了 springkotlin 配置,在该模块中,是可以直接写 kotlin 代码的,并能和 java 代码互相引用。

该图是之前写过的这个文章的内容的代码,在此将其改为 kotlin 了:一种解决Swing中JLabel图片在高分屏上显示不正常的方案Java Swing 在高分屏上图片显示模糊,即 JLab - 掘金

该图是用 kotlin 去写了一个 spring 配置类。

开头有讲到其内置了一个 chromium 内核,用处就是我在里面放了我的个人网站:

日语笔记 - intelyes.club

总结

再回顾下项目结构:

我们只用关心根目录下的配置文件以及每个子项目下的配置文件:

gradle 父子项目中,只用关心根目录下的 build.gradle.ktssettings.gradle.kts ,以及各个子模块的 build.gradle.kts 。这一点和 maven 父子项目相似。

但是配置文件的内容很比 mavenpom.xml 简单:

这个项目由于还没提交到 git ,本地依赖与 native 非常多,代码就暂时不分享了。等到以后整理完成并完善后,会考虑单独写一篇文详细介绍其功能。

如有不懂的欢迎留言讨论!

点击关注公众号,“技术干货” 及时达!

阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

日语语言分析工具 gradle 父子项目 技术积累
相关文章