Gradle構建微服務專案
阿新 • • 發佈:2022-12-03
先說一下初衷把:為啥突然要用Gradle,沒辦法公司領導說要用,後期自研專案都使用Gradle構建......
1、下載安裝
這個就不說了,網上大家搜尋一下,配置一下環境變數即可
2、Groovy的一些語法Gradle任務、檔案操作等等,大家感興趣可以去看看
// TODO 後期補上來
3、使用Gradle建立SpringBoot工程
首先,Gradle中的依賴方式分為三種:
- 本地依賴:依賴本地的某一個jar包,具體的可通過檔案集合、檔案樹的方式指定
- 模組依賴:依賴某個project
- 直接依賴:依賴的型別 依賴的組名 依賴的名稱 依賴的版本號
dependencies { // 本地依賴 implementation files('lib/mysql.jar','lib/junit.jar') // 依賴本地專案下的lib包中的jar檔案 implementation fileTree('dir':'lib',includes: ['xxx.jar'],excludes: ['xxx.jar']) // 指定包含某些jar和排除依賴 // 專案依賴 implementation project(':專案的名稱') // 直接依賴 implementation 'org.junit.jupiter:junit-jupiter-engine:5.8.1' implementation group:'org.junit.jupiter',name:'junit-jupiter-engine',version:'5.8.1' // 完整寫法 }
其次,Gradle依賴配置有5種方式
- 1、implementation:會將指定的依賴新增到編譯路徑,並且會將該依賴打包到輸出,如jar中,但是這個依賴在編譯時不能暴露給其他模組。一句話:依賴不會傳遞
- 2、api:使用api配置的依賴會將對應的依賴新增到編譯路徑,並將依賴打包輸出,但是這個依賴是可以傳遞的,比如模組A依賴模組B,B依賴庫C,模組B在編譯時能夠訪問到庫C
注意:api 與 implementation 區別 ===> api 來定義依賴資訊是可以進行依賴傳遞的,而implementation則不會
- 3、compileOnly:compileOnly修飾的依賴會新增到編譯路徑中,但是不會打包到jar中,因此只能在編譯時訪問,且compileOnly修飾的依賴不會傳遞。
- 4、runtimeOnly:與compileOnly相反,它修飾的依賴不會新增到編譯路徑中,但是被打包到jar中,執行時使用。
- 5、annotationProcessor:這個我也沒整明白
1、建立一個工程
2、配置一下IDEA的Gradle構建工具,他預設使用的是wrapper下的gradle。我們改為自己本地安裝的
改為本地安裝的Gradle
3、在build.gradle檔案中加入依賴
plugins { id 'java' id 'org.springframework.boot' version '2.7.3' // 定義SpringBoot版本,不單獨使用 id 'io.spring.dependency-management' version '1.1.0' } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' //省略版本,原生bom支援,外掛management提供 ...... }
4、測試一下
4、使用Gradle建立SSM多模組工程
1、建立父工程
注意:記得把gradle修改為自己本地安裝的gradle
2、一次建立幾個子工程
gradle-ssm-api:前臺門戶端
gradle-ssm-admin:後臺管理端
gradle-ssm-service:業務處理層
gradle-ssm-mapper:持久層訪問資料庫
gradle-ssm-domain:實體類VO,BO,DTO,POJO......
..... 建立過程我就省略了
最終效果:
專案依賴關係:
3、我們先檢查gradle-ssm-parent工程的settings.gradle
rootProject.name = 'gradle-ssm-parent'
include 'gradle-ssm-api'
include 'gradle-ssm-admin'
include 'gradle-ssm-service'
include 'gradle-ssm-mapper'
include 'gradle-ssm-domain'
4、再修改gradle-ssm-parent工程的build.gradle
plugins {
id 'java'
}
group 'com.qbb'
version '1.0-SNAPSHOT'
// 指定倉庫位置
repositories {
mavenLocal()
mavenCentral()
}
test {
useJUnitPlatform()
}
// 指定子工程的共性資訊
subprojects {
//新增外掛
apply plugin: 'java'
apply plugin: 'java-library'//支援api
//編碼環境jdk版本
sourceCompatibility = 17
//編譯時jdk版本
targetCompatibility = 17
group 'com.qbb'
version '1.0-SNAPSHOT'
/*指定一下字符集,不然打包時有可能會報錯*/
//業務編碼字符集,注意這是指定原始碼解碼的字符集[編譯器]
compileJava.options.encoding "UTF-8"
//測試編碼字符集,注意這是指定原始碼解碼的字符集[編譯器]
compileTestJava.options.encoding "UTF-8"
//編譯JAVA檔案時採用UTF-8:注意這是指定原始碼編碼的字符集【原始檔】
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
//編譯JAVA檔案時採用UTF-8:注意這是指定文件編碼的字符集【原始檔】
tasks.withType(Javadoc) {
options.encoding = "UTF-8"
}
//配置外部屬性
ext {
spring_version = "5.2.5.RELEASE"
}
//依賴的配置
dependencies {
//lombok
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
implementation 'log4j:log4j:1.2.17'
//implementation 'org.slf4j:slf4j-api:1.7.25'
}
test {
useJUnitPlatform()
}
}
project("gradle-ssm-domain") {
dependencies {
// implementation 'org.projectlombok:lombok:1.18.24'
// 這裡使用api的目的就是為了讓lombok依賴可以進行傳遞,上面我們也說過api和implementation的區別
api 'org.projectlombok:lombok:1.18.24'
}
}
project("gradle-ssm-mapper") {
dependencies {
api project(':gradle-ssm-domain')
api 'org.mybatis:mybatis-spring:2.0.6'
api 'com.alibaba:druid:1.2.8'
api 'org.mybatis:mybatis:3.5.8'
api 'mysql:mysql-connector-java:8.0.30'
}
}
project("gradle-ssm-service") {
dependencies {
api project(':gradle-ssm-mapper')
api 'org.springframework:spring-web:5.2.5.RELEASE'
api 'org.springframework:spring-test:5.2.5.RELEASE'
api 'org.springframework:spring-context:5.2.5.RELEASE'
api 'org.springframework:spring-jdbc:5.2.5.RELEASE'
api 'org.aspectj:aspectjweaver:1.9.8'
}
}
project("gradle-ssm-admin") {
apply plugin: 'war' // 打成war寶
dependencies {
implementation project(':gradle-ssm-service')
implementation 'org.springframework:spring-webmvc:5.2.5.RELEASE'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.3'
implementation "com.fasterxml.jackson.core:jackson-annotations:2.12.3"
implementation "com.fasterxml.jackson.core:jackson-core:2.12.3"
compileOnly 'javax.servlet:javax.servlet-api:4.0.1'
implementation 'jstl:jstl:1.2'
}
}
project("gradle-ssm-api") {
apply plugin: 'war'
dependencies {
//implementation project(':gradle-ssm-domain')
implementation project(':gradle-ssm-service')
implementation 'org.springframework:spring-webmvc:5.2.5.RELEASE'
implementation "com.fasterxml.jackson.core:jackson-databind:2.12.3"
implementation "com.fasterxml.jackson.core:jackson-annotations:2.12.3"
implementation "com.fasterxml.jackson.core:jackson-core:2.12.3"
implementation 'jstl:jstl:1.2'
}
}
5、編寫測試類進行測試 (程式碼比較簡單,我直接放在後面的程式碼倉庫了)
clear -> build -> 配置本地的tomcat
注意:我這裡用的是JDK17所以相關的版本也是試錯過得,大家JDK如果不是17,需要注意Spring的版本。不然構建會報錯的
Unsupported class file major version 61
到這本以為全部ok了,但是有一個大坑......我替大家踩了!我在發請求的時候後臺查詢資料庫沒問題,但是前臺一致報錯500...
解決辦法:參考Gradle打包lombok不生效
6、看著好像是完成了,但是還不夠還!這個日期時間我們變成了時間戳,我不喜歡
資料庫中的:
我修改了一下build.gradle依賴資訊
plugins {
id 'java'
}
group 'com.qbb'
version '1.0-SNAPSHOT'
// 指定倉庫位置
repositories {
mavenLocal()
mavenCentral()
}
test {
useJUnitPlatform()
}
// 指定子工程的共性資訊
subprojects {
//新增外掛
apply plugin: 'java'
apply plugin: 'java-library'//支援api
//編碼環境jdk版本
sourceCompatibility = 17
//編譯時jdk版本
targetCompatibility = 17
group 'com.qbb'
version '1.0-SNAPSHOT'
/*指定一下字符集,不然打包時有可能會報錯*/
//業務編碼字符集,注意這是指定原始碼解碼的字符集[編譯器]
compileJava.options.encoding "UTF-8"
//測試編碼字符集,注意這是指定原始碼解碼的字符集[編譯器]
compileTestJava.options.encoding "UTF-8"
//編譯JAVA檔案時採用UTF-8:注意這是指定原始碼編碼的字符集【原始檔】
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
//編譯JAVA檔案時採用UTF-8:注意這是指定文件編碼的字符集【原始檔】
tasks.withType(Javadoc) {
options.encoding = "UTF-8"
}
//配置外部屬性
ext {
spring_version = "5.3.22"
}
//依賴的配置
dependencies {
//lombok
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
implementation 'log4j:log4j:1.2.17'
//implementation 'org.slf4j:slf4j-api:1.7.25'
}
test {
useJUnitPlatform()
}
}
project("gradle-ssm-domain") {
dependencies {
// implementation 'org.projectlombok:lombok:1.18.24'
// 這裡使用api的目的就是為了讓lombok依賴可以進行傳遞,上面我們也說過api和implementation的區別
// api 'org.projectlombok:lombok:1.18.24'
// 解決Gradle打包後lombok不生效
api 'org.projectlombok:lombok:1.18.24'
annotationProcessor 'org.projectlombok:lombok:1.18.24'
// 在domain層加入,後續依賴domain的模組可繼續使用
api 'com.fasterxml.jackson.core:jackson-databind:2.12.3'
api "com.fasterxml.jackson.core:jackson-annotations:2.12.3"
api "com.fasterxml.jackson.core:jackson-core:2.12.3"
}
}
project("gradle-ssm-mapper") {
dependencies {
api project(':gradle-ssm-domain')
api 'org.mybatis:mybatis-spring:2.0.6'
api 'com.alibaba:druid:1.2.8'
api 'org.mybatis:mybatis:3.5.8'
api 'mysql:mysql-connector-java:8.0.30'
}
}
project("gradle-ssm-service") {
dependencies {
api project(':gradle-ssm-mapper')
api 'org.springframework:spring-web:5.3.22'
api 'org.springframework:spring-test:5.3.22'
api 'org.springframework:spring-context:5.3.22'
api 'org.springframework:spring-jdbc:5.3.22'
api 'org.aspectj:aspectjweaver:1.9.8'
}
}
project("gradle-ssm-admin") {
apply plugin: 'war' // 打成war寶
dependencies {
implementation project(':gradle-ssm-service')
implementation 'org.springframework:spring-webmvc:5.3.22'
// implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.3'
// implementation "com.fasterxml.jackson.core:jackson-annotations:2.12.3"
// implementation "com.fasterxml.jackson.core:jackson-core:2.12.3"
compileOnly 'javax.servlet:javax.servlet-api:4.0.1'
implementation 'jstl:jstl:1.2'
}
}
project("gradle-ssm-api") {
apply plugin: 'war'
dependencies {
//implementation project(':gradle-ssm-domain')
implementation project(':gradle-ssm-service')
implementation 'org.springframework:spring-webmvc:5.3.22'
// implementation "com.fasterxml.jackson.core:jackson-databind:2.12.3"
// implementation "com.fasterxml.jackson.core:jackson-annotations:2.12.3"
// implementation "com.fasterxml.jackson.core:jackson-core:2.12.3"
implementation 'jstl:jstl:1.2'
}
}
在實體類上序列化一下
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
本以為大功告成,結果又報了這個錯
03-Dec-2022 17:59:42.295 涓ラ噸 [http-nio-8080-exec-4] org.apache.catalina.core.StandardWrapperValve.invoke 鍦ㄨ礬寰勪負/ssm鐨勪笂涓嬫枃涓紝Servlet[DispatcherServlet]鐨凷ervlet.service錛堬級寮曞彂浜嗗叿鏈夋牴鏈師鍥犵殑寮傚父Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class java.time.LocalDateTime]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: java.util.ArrayList[0]->com.qbb.User["createTime"])
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: java.util.ArrayList[0]->com.qbb.User["createTime"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1276)
at com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer.serialize(UnsupportedTypeSerializer.java:35)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:400)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1510)
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1006)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:456)
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:104)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:290)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:183)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:135)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1070)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:670)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:779)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:94)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
解決辦法:加入一個依賴就好了
project("gradle-ssm-domain") {
dependencies {
......
// 解決 Java 8 date/time type `java.time.LocalDateTime` not supported
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.0'
......
}
}
至此Gradle構建SSM多模組專案完成