一、创建项目
1、创建主项目
按创建springboot项目的创建方式创建就行,创建完的结构。然后删除src目录。
2、创建模块项目
创建模块项目New-》Module-》New Module(或Spring Initializr)。
依次创建service删除文件,然后创建工程等,创建后如下:
3、setting.gradle文件
创建完工程后,会自动在这个文件中添加下面的内容,表示将子模块引入
二、配置build.gradle文件
构建单体的多模块项目,demo-web作为启动项目,依赖service
说明文档:https://docs.gradle.org/current/userguide/gradle_directories.htmlGradle Directorieshttps://docs.gradle.org/current/userguide/gradle_directories.html
1、修改根目录的build.gradle
用于管理子模块。主要是hi设置下载仓库、依赖包、插件等信息。主要定义一些公共的内容。
打包相关的定义也可以统一在跟目录下的这个文件写,暂时定义到各模块自己的文件里。
bash
buildscript {
// 指定插件的仓库
repositories {
jcenter()
mavenCentral()
maven { url 'https://jitpack.io' } // 添加这一行
}
// 定义插件及其版本
// dependencies {
// classpath "org.springframework.boot:spring-boot-gradle-plugin:2.5.5"
// }
}
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.7'
id 'io.spring.dependency-management' version '1.1.5'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
subprojects {
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
repositories {
mavenCentral()
}
// dependencies {
// implementation 'org.springframework.boot:spring-boot-starter'
// }
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}
}
2、修改模块项目的build.gradle
以demo-web为例。增加依赖的项目包,也可以增加其他的依赖
bash
bootJar {
archiveBaseName = 'demo-web'
archiveVersion = '0.0.1-SNAPSHOT'
}
dependencies {
implementation project(':service:demo-api')
implementation project(':service:demo-service')
}
demo-service工程。定义只打jar。bootjar定位false
bash
bootJar {
enabled(false)
archiveBaseName = 'demo-service'
archiveVersion = '0.0.1-SNAPSHOT'
}
jar {
enabled(true)
}
dependencies {
implementation project(':service:demo-api')
}
三、启动打包测试
1、编写接口服务等
注意要增加@service注解
java
public interface IDemoService {
String test();
}
java
@Service
public class DemoService implements IDemoService {
@Override
public String test() {
return "demo service";
}
}
2、编写controller
java
@RestController
@RequestMapping("/demo")
public class DemoController {
@Autowired
private IDemoService demoService;
@GetMapping("test")
public String test(){
return demoService.test();
}
}
3、编写启动类
注意加@SpringBootApplication注解。最好放在包的最外层
java
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
4、启动测试
可以用idea启动测试或打jar启动测试
5、打包验证
点击gradle的bootjar可以生成jar包
通过 jar tf .\demo-web-0.0.1-SNAPSHOT.jar 命令可以查看生成的jar文件
bash
PS C:\study\demo\web\demo-web\build\libs> jar tf .\demo-web-0.0.1-SNAPSHOT.jar
META-INF/
META-INF/MANIFEST.MF
META-INF/services/
META-INF/services/java.nio.file.spi.FileSystemProvider
org/
org/springframework/
org/springframework/boot/
org/springframework/boot/loader/
org/springframework/boot/loader/jar/
org/springframework/boot/loader/jar/ManifestInfo.class
org/springframework/boot/loader/jar/MetaInfVersionsInfo.class
org/springframework/boot/loader/jar/NestedJarFile$JarEntriesEnumeration.class
org/springframework/boot/loader/jar/NestedJarFile$JarEntryInflaterInputStream.class
org/springframework/boot/loader/jar/NestedJarFile$JarEntryInputStream.class
org/springframework/boot/loader/jar/NestedJarFile$NestedJarEntry.class
org/springframework/boot/loader/jar/NestedJarFile$RawZipDataInputStream.class
org/springframework/boot/loader/jar/NestedJarFile$ZipContentEntriesSpliterator.class
org/springframework/boot/loader/jar/NestedJarFile.class
org/springframework/boot/loader/jar/NestedJarFileResources.class
org/springframework/boot/loader/jar/SecurityInfo.class
org/springframework/boot/loader/jar/ZipInflaterInputStream.class
org/springframework/boot/loader/jarmode/
org/springframework/boot/loader/jarmode/JarMode.class
org/springframework/boot/loader/launch/
org/springframework/boot/loader/launch/Archive$Entry.class
org/springframework/boot/loader/launch/Archive.class
org/springframework/boot/loader/launch/ClassPathIndexFile.class
org/springframework/boot/loader/launch/ExecutableArchiveLauncher.class
org/springframework/boot/loader/launch/ExplodedArchive$FileArchiveEntry.class
org/springframework/boot/loader/launch/ExplodedArchive.class
org/springframework/boot/loader/launch/JarFileArchive$JarArchiveEntry.class
org/springframework/boot/loader/launch/JarFileArchive.class
org/springframework/boot/loader/launch/JarLauncher.class
org/springframework/boot/loader/launch/JarModeRunner.class
org/springframework/boot/loader/launch/LaunchedClassLoader$DefinePackageCallType.class
org/springframework/boot/loader/launch/LaunchedClassLoader.class
org/springframework/boot/loader/launch/Launcher.class
org/springframework/boot/loader/launch/PropertiesLauncher$Instantiator$Using.class
org/springframework/boot/loader/launch/PropertiesLauncher$Instantiator.class
org/springframework/boot/loader/launch/PropertiesLauncher.class
org/springframework/boot/loader/launch/SystemPropertyUtils.class
org/springframework/boot/loader/launch/WarLauncher.class
org/springframework/boot/loader/log/
org/springframework/boot/loader/log/DebugLogger$DisabledDebugLogger.class
org/springframework/boot/loader/log/DebugLogger$SystemErrDebugLogger.class
org/springframework/boot/loader/log/DebugLogger.class
org/springframework/boot/loader/net/
org/springframework/boot/loader/net/protocol/
org/springframework/boot/loader/net/protocol/Handlers.class
org/springframework/boot/loader/net/protocol/jar/
org/springframework/boot/loader/net/protocol/jar/Canonicalizer.class
org/springframework/boot/loader/net/protocol/jar/Handler.class
org/springframework/boot/loader/net/protocol/jar/JarFileUrlKey.class
org/springframework/boot/loader/net/protocol/jar/JarUrl.class
org/springframework/boot/loader/net/protocol/jar/JarUrlClassLoader$OptimizedEnumeration.class
org/springframework/boot/loader/net/protocol/jar/JarUrlClassLoader.class
org/springframework/boot/loader/net/protocol/jar/JarUrlConnection$ConnectionInputStream.class
org/springframework/boot/loader/net/protocol/jar/JarUrlConnection$EmptyUrlStreamHandler.class
org/springframework/boot/loader/net/protocol/jar/JarUrlConnection.class
org/springframework/boot/loader/net/protocol/jar/LazyDelegatingInputStream.class
org/springframework/boot/loader/net/protocol/jar/Optimizations.class
org/springframework/boot/loader/net/protocol/jar/UrlJarEntry.class
org/springframework/boot/loader/net/protocol/jar/UrlJarFile.class
org/springframework/boot/loader/net/protocol/jar/UrlJarFileFactory.class
org/springframework/boot/loader/net/protocol/jar/UrlJarFiles$Cache.class
org/springframework/boot/loader/net/protocol/jar/UrlJarFiles.class
org/springframework/boot/loader/net/protocol/jar/UrlJarManifest$ManifestSupplier.class
org/springframework/boot/loader/net/protocol/jar/UrlJarManifest.class
org/springframework/boot/loader/net/protocol/jar/UrlNestedJarFile.class
org/springframework/boot/loader/net/protocol/nested/
org/springframework/boot/loader/net/protocol/nested/Handler.class
org/springframework/boot/loader/net/protocol/nested/NestedLocation.class
org/springframework/boot/loader/net/protocol/nested/NestedUrlConnection$ConnectionInputStream.class
org/springframework/boot/loader/net/protocol/nested/NestedUrlConnection.class
org/springframework/boot/loader/net/protocol/nested/NestedUrlConnectionResources.class
org/springframework/boot/loader/net/util/
org/springframework/boot/loader/net/util/UrlDecoder.class
org/springframework/boot/loader/nio/
org/springframework/boot/loader/nio/file/
org/springframework/boot/loader/nio/file/NestedByteChannel$Resources.class
org/springframework/boot/loader/nio/file/NestedByteChannel.class
org/springframework/boot/loader/nio/file/NestedFileStore.class
org/springframework/boot/loader/nio/file/NestedFileSystem.class
org/springframework/boot/loader/nio/file/NestedFileSystemProvider.class
org/springframework/boot/loader/nio/file/NestedPath.class
org/springframework/boot/loader/nio/file/UriPathEncoder.class
org/springframework/boot/loader/ref/
org/springframework/boot/loader/ref/Cleaner.class
org/springframework/boot/loader/ref/DefaultCleaner.class
org/springframework/boot/loader/zip/
org/springframework/boot/loader/zip/ByteArrayDataBlock.class
org/springframework/boot/loader/zip/CloseableDataBlock.class
org/springframework/boot/loader/zip/DataBlock.class
org/springframework/boot/loader/zip/DataBlockInputStream.class
org/springframework/boot/loader/zip/FileDataBlock$FileAccess.class
org/springframework/boot/loader/zip/FileDataBlock$Tracker$1.class
org/springframework/boot/loader/zip/FileDataBlock$Tracker.class
org/springframework/boot/loader/zip/FileDataBlock.class
org/springframework/boot/loader/zip/NameOffsetLookups.class
org/springframework/boot/loader/zip/VirtualDataBlock.class
org/springframework/boot/loader/zip/VirtualZipDataBlock$DataPart.class
org/springframework/boot/loader/zip/VirtualZipDataBlock.class
org/springframework/boot/loader/zip/Zip64EndOfCentralDirectoryLocator.class
org/springframework/boot/loader/zip/Zip64EndOfCentralDirectoryRecord.class
org/springframework/boot/loader/zip/ZipCentralDirectoryFileHeaderRecord.class
org/springframework/boot/loader/zip/ZipContent$Entry.class
org/springframework/boot/loader/zip/ZipContent$Kind.class
org/springframework/boot/loader/zip/ZipContent$Loader.class
org/springframework/boot/loader/zip/ZipContent$Source.class
org/springframework/boot/loader/zip/ZipContent.class
org/springframework/boot/loader/zip/ZipDataDescriptorRecord.class
org/springframework/boot/loader/zip/ZipEndOfCentralDirectoryRecord$Located.class
org/springframework/boot/loader/zip/ZipEndOfCentralDirectoryRecord.class
org/springframework/boot/loader/zip/ZipLocalFileHeaderRecord.class
org/springframework/boot/loader/zip/ZipString$CompareType.class
org/springframework/boot/loader/zip/ZipString.class
BOOT-INF/
BOOT-INF/classes/
BOOT-INF/classes/com/
BOOT-INF/classes/com/example/
BOOT-INF/classes/com/example/controller/
BOOT-INF/classes/com/example/controller/DemoController.class
BOOT-INF/classes/com/example/DemoApplication.class
BOOT-INF/classes/application.properties
BOOT-INF/lib/
BOOT-INF/lib/demo-service-plain.jar
BOOT-INF/lib/demo-api-plain.jar
BOOT-INF/lib/micrometer-observation-1.12.7.jar
BOOT-INF/lib/micrometer-observation-1.12.7.jar
BOOT-INF/lib/logback-classic-1.4.14.jar
BOOT-INF/lib/log4j-to-slf4j-2.21.1.jar
BOOT-INF/lib/jul-to-slf4j-2.0.13.jar
BOOT-INF/lib/spring-jcl-6.1.10.jar
BOOT-INF/lib/micrometer-commons-1.12.7.jar
BOOT-INF/lib/logback-core-1.4.14.jar
BOOT-INF/lib/slf4j-api-2.0.13.jar
BOOT-INF/lib/log4j-api-2.21.1.jar
BOOT-INF/lib/spring-boot-jarmode-layertools-3.2.7.jar
BOOT-INF/classpath.idx
BOOT-INF/layers.idx
可以通过这个命令启动jar包,注意jdk版本要一致
bash
java -jar .\demo-web-0.0.1-SNAPSHOT.jar
四、遇到的问题
1、通过根目录下的bootJar打包失败
各项目下的bootJar不报错,只有根目录下的报错
报错1:
bash
Execution failed for task ':bootJar'.
> Could not resolve all artifacts for configuration ':detachedConfiguration1'.
> Cannot resolve external dependency org.springframework.boot:spring-boot-dependencies:3.2.7 because no repositories are defined.
Required by:
project :
Possible solution:
- Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html
解决方案:
根目录下的build.gradle没有定义allproject,把subproject改成allproject后包另外一个错
报错2:
bash
Execution failed for task ':bootJar'.
> Error while evaluating property 'mainClass' of task ':bootJar'.
> Failed to calculate the value of task ':bootJar' property 'mainClass'.
> Main class name has not been configured and it could not be resolved from classpath
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
BUILD FAILED in 10s
2 actionable tasks: 1 executed, 1 up-to-date
解决方案:
增加mainClass的指定。两种方案都可以
bash
springBoot {
mainClass = 'com.example.DemoApplication'
}
bootJar {
archiveBaseName = 'demo-web'
archiveVersion = '0.0.1-SNAPSHOT'
includeEmptyDirs = true
// mainClass = 'com.example.DemoApplication'
}
dependencies {
implementation project(':service:demo-api')
implementation project(':service:demo-service')
}
报错3:
bash
Execution failed for task ':service:bootJar'.
> Error while evaluating property 'mainClass' of task ':service:bootJar'.
> Failed to calculate the value of task ':service:bootJar' property 'mainClass'.
> Main class name has not been configured and it could not be resolved from classpath
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
For more on this, please refer to https://docs.gradle.org/8.8/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
BUILD FAILED in 346ms
2 actionable tasks: 2 executed