Docker容器Java項(xiàng)目打包與部署全過程
一、基礎(chǔ)概念
(一)Docker鏡像
Docker鏡像是一個(gè)包含代碼、運(yùn)行時(shí)環(huán)境、庫、環(huán)境變量和配置文件的不可變模板,它是創(chuàng)建Docker容器的基礎(chǔ)。如果把Docker容器比作按照食譜做出的食物,那么Docker鏡像就是那份詳細(xì)的食譜,里面精確地規(guī)定了制作這道“食物”所需的各種“食材”和“步驟”。
例如,一個(gè)用于運(yùn)行Java項(xiàng)目的Docker鏡像,會(huì)包含Java運(yùn)行時(shí)環(huán)境(JRE)、項(xiàng)目的JAR包、項(xiàng)目運(yùn)行所需的依賴庫以及相關(guān)的配置信息等。當(dāng)我們基于這個(gè)鏡像創(chuàng)建容器時(shí),就如同按照食譜制作食物,容器會(huì)依據(jù)鏡像中的內(nèi)容來運(yùn)行Java項(xiàng)目。
(二)Java項(xiàng)目部署常見方式
傳統(tǒng)的Java項(xiàng)目部署方式有很多,比如直接在服務(wù)器上安裝JDK,然后將打包好的JAR包或WAR包上傳到服務(wù)器,通過命令啟動(dòng)項(xiàng)目。這種方式需要手動(dòng)配置服務(wù)器環(huán)境,包括安裝JDK、設(shè)置環(huán)境變量、處理依賴等,不同服務(wù)器之間的環(huán)境可能存在差異,容易導(dǎo)致項(xiàng)目在不同環(huán)境中運(yùn)行出現(xiàn)問題。
還有一種方式是使用虛擬機(jī),在虛擬機(jī)中配置好Java運(yùn)行環(huán)境,然后部署項(xiàng)目。但虛擬機(jī)資源占用較大,啟動(dòng)速度慢,且不易于擴(kuò)展和管理。
而使用Docker部署Java項(xiàng)目,可以將項(xiàng)目及其依賴環(huán)境打包到一個(gè)鏡像中,實(shí)現(xiàn)了“一次構(gòu)建,到處運(yùn)行”,避免了環(huán)境差異帶來的問題,同時(shí)也便于項(xiàng)目的擴(kuò)展、管理和版本控制。
二、Java項(xiàng)目準(zhǔn)備
(一)Java項(xiàng)目結(jié)構(gòu)
一個(gè)典型的Java項(xiàng)目結(jié)構(gòu)如下:
my-java-project/ ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ ├── controller/ │ │ │ ├── service/ │ │ │ ├── model/ │ │ │ └── Main.java │ │ └── resources/ │ │ ├── application.properties │ │ └── logback.xml │ └── test/ │ └── java/ │ └── com/ │ └── example/ │ ├── controller/ │ └── service/ ├── pom.xml └── README.md
src/main/java:存放項(xiàng)目的主要Java源代碼。src/main/resources:存放項(xiàng)目的配置文件、資源文件等。src/test/java:存放項(xiàng)目的測(cè)試代碼。pom.xml:Maven項(xiàng)目的配置文件,用于管理項(xiàng)目的依賴、構(gòu)建等信息。
(二)依賴管理
在Java項(xiàng)目中,通常使用Maven或Gradle進(jìn)行依賴管理。以Maven為例,pom.xml文件中會(huì)定義項(xiàng)目所需的依賴,例如:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
當(dāng)執(zhí)行mvn clean package命令時(shí),Maven會(huì)自動(dòng)從遠(yuǎn)程倉庫下載所需的依賴,并將其添加到項(xiàng)目的構(gòu)建路徑中。
(三)打包方式
Java項(xiàng)目常見的打包方式有JAR和WAR。
- JAR(Java Archive)文件是一種用于打包Java類文件、相關(guān)資源和元數(shù)據(jù)的歸檔文件格式,通常用于封裝獨(dú)立的Java應(yīng)用程序或庫。對(duì)于Spring Boot項(xiàng)目,默認(rèn)打包為JAR包,其中包含了嵌入式的Web服務(wù)器(如Tomcat),可以直接通過
java -jar命令運(yùn)行。 - WAR(Web Application Archive)文件則是專為Web應(yīng)用程序設(shè)計(jì)的歸檔格式,包含Servlet、JSP、HTML、CSS、JavaScript等Web相關(guān)資源。WAR包需要部署到外部的Web服務(wù)器(如Tomcat、Jetty)中才能運(yùn)行。
在Docker部署中,如果是Spring Boot等包含嵌入式服務(wù)器的項(xiàng)目,選擇JAR包更為方便,因?yàn)榭梢灾苯釉谌萜髦型ㄟ^java -jar命令啟動(dòng)。如果是傳統(tǒng)的Web項(xiàng)目,沒有嵌入式服務(wù)器,則需要打包為WAR包,并在Docker鏡像中配置相應(yīng)的Web服務(wù)器來部署。
三、Dockerfile編寫
Dockerfile是一個(gè)文本文件,包含了一系列構(gòu)建Docker鏡像的指令。通過編寫Dockerfile,可以定義如何將Java項(xiàng)目及其依賴環(huán)境打包到鏡像中。
(一)基礎(chǔ)鏡像選擇
選擇合適的基礎(chǔ)鏡像是編寫Dockerfile的第一步。對(duì)于Java項(xiàng)目,常用的基礎(chǔ)鏡像是openjdk??梢愿鶕?jù)項(xiàng)目所需的Java版本選擇相應(yīng)的openjdk鏡像,同時(shí)還可以選擇不同的操作系統(tǒng)版本,如Alpine版本的鏡像體積更小。
例如,選擇openjdk 11的Alpine版本作為基礎(chǔ)鏡像:
FROM openjdk:11-jre-alpine
openjdk:11-jre-alpine表示該鏡像包含Java 11的運(yùn)行時(shí)環(huán)境(JRE),基于Alpine Linux,體積較小,適合作為Java項(xiàng)目的基礎(chǔ)鏡像。
(二)工作目錄設(shè)置
設(shè)置工作目錄可以使后續(xù)的命令操作更加清晰,避免文件路徑混亂。使用WORKDIR指令設(shè)置工作目錄:
WORKDIR /app
該指令會(huì)在鏡像中創(chuàng)建/app目錄,并將后續(xù)命令的工作目錄設(shè)置為/app。
(三)文件復(fù)制
需要將打包好的Java項(xiàng)目JAR包復(fù)制到鏡像中。使用COPY指令:
COPY target/my-java-project-1.0.0.jar app.jar
這條指令將本地項(xiàng)目中target目錄下的my-java-project-1.0.0.jar文件復(fù)制到鏡像的/app目錄下,并命名為app.jar。
(四)依賴安裝
如果項(xiàng)目在運(yùn)行過程中需要額外的依賴,可以通過相應(yīng)的命令進(jìn)行安裝。例如,在Alpine基礎(chǔ)鏡像中安裝一些工具:
RUN apk add --no-cache curl
apk是Alpine Linux的包管理工具,--no-cache表示不緩存包索引,減少鏡像體積。這條指令會(huì)在鏡像中安裝curl工具。
(五)端口暴露
Java項(xiàng)目通常會(huì)占用一個(gè)端口運(yùn)行,需要在鏡像中暴露該端口,以便外部可以訪問容器中的應(yīng)用。使用EXPOSE指令:
EXPOSE 8080
這條指令表示該鏡像中的應(yīng)用會(huì)監(jiān)聽8080端口。需要注意的是,EXPOSE指令只是聲明了容器運(yùn)行時(shí)會(huì)使用的端口,并不會(huì)自動(dòng)將端口映射到宿主機(jī),還需要在運(yùn)行容器時(shí)通過-p參數(shù)進(jìn)行端口映射。
(六)啟動(dòng)命令設(shè)置
最后,需要設(shè)置容器啟動(dòng)時(shí)運(yùn)行的命令,即啟動(dòng)Java項(xiàng)目。使用CMD指令:
CMD ["java", "-jar", "app.jar"]
這條指令表示當(dāng)容器啟動(dòng)時(shí),會(huì)執(zhí)行java -jar app.jar命令,啟動(dòng)Java項(xiàng)目。
完整的Dockerfile示例:
# 基礎(chǔ)鏡像 FROM openjdk:11-jre-alpine # 設(shè)置工作目錄 WORKDIR /app # 復(fù)制JAR包到鏡像中 COPY target/my-java-project-1.0.0.jar app.jar # 暴露端口 EXPOSE 8080 # 啟動(dòng)命令 CMD ["java", "-jar", "app.jar"]
四、鏡像構(gòu)建
編寫好Dockerfile后,就可以使用docker build命令構(gòu)建Docker鏡像了。
(一)基本構(gòu)建命令
在Dockerfile所在的目錄下,執(zhí)行以下命令:
docker build -t my-java-app:1.0.0 .
-t:指定鏡像的標(biāo)簽,格式為倉庫名:標(biāo)簽,這里my-java-app是鏡像名,1.0.0是版本標(biāo)簽。.:表示Dockerfile所在的當(dāng)前目錄,Docker會(huì)從該目錄開始查找構(gòu)建鏡像所需的文件。
執(zhí)行命令后,Docker會(huì)按照Dockerfile中的指令逐步構(gòu)建鏡像。構(gòu)建過程中,會(huì)輸出每一步的操作信息,如果出現(xiàn)錯(cuò)誤,會(huì)提示相應(yīng)的錯(cuò)誤信息,需要根據(jù)錯(cuò)誤信息修改Dockerfile或相關(guān)文件后重新構(gòu)建。
(二)多階段構(gòu)建
多階段構(gòu)建可以減少鏡像的大小,只將最終需要運(yùn)行的文件復(fù)制到最終的鏡像中,避免把構(gòu)建過程中產(chǎn)生的不必要文件也包含進(jìn)來。
例如,對(duì)于一個(gè)使用Maven構(gòu)建的Java項(xiàng)目,可以分為兩個(gè)階段:
- 第一個(gè)階段:使用包含Maven的基礎(chǔ)鏡像,進(jìn)行項(xiàng)目的編譯和打包,生成JAR包。
- 第二個(gè)階段:使用openjdk的基礎(chǔ)鏡像,將第一個(gè)階段生成的JAR包復(fù)制到該鏡像中,作為最終的運(yùn)行鏡像。
多階段構(gòu)建的Dockerfile示例:
# 第一階段:構(gòu)建階段 FROM maven:3.8.5-openjdk-11 AS builder # 設(shè)置工作目錄 WORKDIR /app # 復(fù)制pom.xml和源代碼 COPY pom.xml . COPY src ./src # 編譯打包 RUN mvn clean package -Dmaven.test.skip=true # 第二階段:運(yùn)行階段 FROM openjdk:11-jre-alpine # 設(shè)置工作目錄 WORKDIR /app # 從第一階段復(fù)制JAR包到當(dāng)前鏡像 COPY --from=builder /app/target/my-java-project-1.0.0.jar app.jar # 暴露端口 EXPOSE 8080 # 啟動(dòng)命令 CMD ["java", "-jar", "app.jar"]
使用多階段構(gòu)建時(shí),構(gòu)建命令不變,仍然是docker build -t my-java-app:1.0.0 .。通過這種方式,最終的鏡像只包含了運(yùn)行Java項(xiàng)目所需的JRE和JAR包,大大減小了鏡像體積。
(三)構(gòu)建緩存優(yōu)化
Docker在構(gòu)建鏡像時(shí),會(huì)對(duì)每一步指令進(jìn)行緩存,如果后續(xù)構(gòu)建時(shí)指令沒有變化,會(huì)直接使用緩存,從而提高構(gòu)建效率。為了充分利用緩存,可以合理安排Dockerfile中指令的順序。
通常,將變化較少的指令放在前面,變化較多的指令放在后面。例如,對(duì)于Maven項(xiàng)目,pom.xml文件的變化頻率相對(duì)較低,而源代碼的變化頻率較高。在多階段構(gòu)建中,可以先復(fù)制pom.xml文件,下載依賴,然后再復(fù)制源代碼進(jìn)行編譯打包。這樣,當(dāng)源代碼發(fā)生變化時(shí),只有復(fù)制源代碼和編譯打包的步驟會(huì)重新執(zhí)行,而下載依賴的步驟可以利用緩存。
優(yōu)化后的多階段構(gòu)建Dockerfile示例:
# 第一階段:構(gòu)建階段 FROM maven:3.8.5-openjdk-11 AS builder # 設(shè)置工作目錄 WORKDIR /app # 復(fù)制pom.xml COPY pom.xml . # 下載依賴 RUN mvn dependency:go-offline # 復(fù)制源代碼 COPY src ./src # 編譯打包 RUN mvn clean package -Dmaven.test.skip=true # 第二階段:運(yùn)行階段 FROM openjdk:11-jre-alpine # 設(shè)置工作目錄 WORKDIR /app # 從第一階段復(fù)制JAR包到當(dāng)前鏡像 COPY --from=builder /app/target/my-java-project-1.0.0.jar app.jar # 暴露端口 EXPOSE 8080 # 啟動(dòng)命令 CMD ["java", "-jar", "app.jar"]
五、鏡像測(cè)試和驗(yàn)證
構(gòu)建好Docker鏡像后,需要進(jìn)行測(cè)試和驗(yàn)證,確保應(yīng)用程序能正常啟動(dòng)和運(yùn)行。
(一)運(yùn)行容器
使用docker run命令運(yùn)行容器:
docker run -d -p 8080:8080 --name my-java-container my-java-app:1.0.0
-d:表示后臺(tái)運(yùn)行容器。-p 8080:8080:將宿主機(jī)的8080端口映射到容器的8080端口,這樣可以通過宿主機(jī)的8080端口訪問容器中的應(yīng)用。--name my-java-container:為容器指定一個(gè)名稱。my-java-app:1.0.0:指定要運(yùn)行的鏡像。
(二)檢查容器狀態(tài)
使用docker ps命令查看容器的運(yùn)行狀態(tài):
docker ps
如果容器狀態(tài)為Up,表示容器正在正常運(yùn)行。如果容器沒有正常運(yùn)行,可以使用docker logs命令查看容器的日志,排查問題:
docker logs my-java-container
(三)訪問應(yīng)用程序
通過瀏覽器或curl命令訪問宿主機(jī)的8080端口,檢查應(yīng)用程序是否能正常響應(yīng)。例如:
curl http://localhost:8080
如果能得到應(yīng)用程序的正常響應(yīng),說明鏡像構(gòu)建和部署成功。
六、Docker鏡像倉庫
Docker鏡像倉庫用于存儲(chǔ)和管理Docker鏡像,方便在不同環(huán)境中拉取和使用鏡像。
(一)公共鏡像倉庫
常用的公共鏡像倉庫有Docker Hub、阿里云容器鏡像服務(wù)、騰訊云容器鏡像服務(wù)等。
Docker Hub是最大的公共Docker鏡像倉庫,包含了大量的官方和社區(qū)鏡像??梢酝ㄟ^docker pull命令從Docker Hub拉取鏡像,例如:
docker pull openjdk:11-jre-alpine
(二)私有鏡像倉庫搭建
對(duì)于企業(yè)內(nèi)部的項(xiàng)目,通常會(huì)搭建私有鏡像倉庫,以保證鏡像的安全性和私密性??梢允褂肈ocker Registry來搭建私有鏡像倉庫。
- 拉取Docker Registry鏡像:
docker pull registry:2
- 運(yùn)行Docker Registry容器:
docker run -d -p 5000:5000 --name my-registry -v /my/registry/data:/var/lib/registry registry:2
-v /my/registry/data:/var/lib/registry:將宿主機(jī)的/my/registry/data目錄掛載到容器的/var/lib/registry目錄,用于持久化存儲(chǔ)鏡像數(shù)據(jù)。
- 配置Docker客戶端,允許訪問私有倉庫。對(duì)于Linux系統(tǒng),需要在
/etc/docker/daemon.json文件中添加以下內(nèi)容:
{
"insecure-registries": ["localhost:5000"]
}
然后重啟Docker服務(wù):
systemctl restart docker
(三)鏡像推送和拉取
- 給鏡像打標(biāo)簽,標(biāo)簽格式為
私有倉庫地址:端口/鏡像名:標(biāo)簽:
docker tag my-java-app:1.0.0 localhost:5000/my-java-app:1.0.0
- 將鏡像推送到私有倉庫:
docker push localhost:5000/my-java-app:1.0.0
- 在其他環(huán)境中拉取私有倉庫的鏡像:
docker pull localhost:5000/my-java-app:1.0.0
七、Docker Compose使用
當(dāng)Java項(xiàng)目涉及到多個(gè)服務(wù),比如數(shù)據(jù)庫、緩存等,使用Docker Compose可以方便地定義和運(yùn)行多個(gè)容器應(yīng)用。
(一)docker-compose.yml文件編寫
docker-compose.yml文件用于定義多個(gè)服務(wù)的配置。例如,一個(gè)Java應(yīng)用服務(wù)和一個(gè)MySQL數(shù)據(jù)庫服務(wù)的配置:
version: '3'
services:
java-app:
build: .
ports:
- "8080:8080"
depends_on:
- mysql
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/my_db
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=123456
mysql:
image: mysql:8.0
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=my_db
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:
version: '3':指定Docker Compose的版本。services:定義各個(gè)服務(wù)。java-app:Java應(yīng)用服務(wù),build: .表示根據(jù)當(dāng)前目錄的Dockerfile構(gòu)建鏡像,ports指定端口映射,depends_on表示該服務(wù)依賴于mysql服務(wù),environment設(shè)置環(huán)境變量,用于配置數(shù)據(jù)庫連接信息。mysql:MySQL數(shù)據(jù)庫服務(wù),image指定使用的鏡像,ports指定端口映射,environment設(shè)置數(shù)據(jù)庫的root密碼和初始化數(shù)據(jù)庫名,volumes用于持久化存儲(chǔ)數(shù)據(jù)庫數(shù)據(jù)。
volumes:定義數(shù)據(jù)卷,用于持久化存儲(chǔ)數(shù)據(jù)。
(二)啟動(dòng)服務(wù)
在docker-compose.yml文件所在的目錄下,執(zhí)行以下命令啟動(dòng)所有服務(wù):
docker-compose up -d
-d表示后臺(tái)運(yùn)行服務(wù)。
(三)停止服務(wù)
執(zhí)行以下命令停止所有服務(wù):
docker-compose down
如果需要?jiǎng)h除數(shù)據(jù)卷,可以加上-v參數(shù):
docker-compose down -v
(四)查看服務(wù)狀態(tài)
執(zhí)行以下命令查看服務(wù)的運(yùn)行狀態(tài):
docker-compose ps
(五)查看服務(wù)日志
執(zhí)行以下命令查看某個(gè)服務(wù)的日志:
docker-compose logs java-app
八、高級(jí)話題
(一)鏡像優(yōu)化
- 選擇合適的基礎(chǔ)鏡像:盡量使用體積小的基礎(chǔ)鏡像,如Alpine版本的鏡像。例如,
openjdk:11-jre-alpine比openjdk:11-jre體積小很多。 - 減少鏡像層數(shù):Docker鏡像由多個(gè)層組成,每一條指令都會(huì)創(chuàng)建一個(gè)新的層??梢詫⒍鄠€(gè)相關(guān)的指令合并為一個(gè),減少鏡像層數(shù)。例如,將多個(gè)
RUN指令合并:
RUN apk add --no-cache curl && \
apk add --no-cache wget
- 清理不必要的依賴和文件:在構(gòu)建過程中,及時(shí)清理不需要的文件和依賴,減少鏡像體積。例如,在Maven構(gòu)建后,清理Maven的本地倉庫緩存:
RUN mvn clean package -Dmaven.test.skip=true && \
rm -rf ~/.m2/repository
(二)安全加固
- 避免使用root用戶運(yùn)行容器:在Dockerfile中創(chuàng)建普通用戶,并使用該用戶運(yùn)行應(yīng)用程序,限制容器的權(quán)限。
# 創(chuàng)建普通用戶 RUN addgroup -S appgroup && adduser -S appuser -G appgroup # 切換到普通用戶 USER appuser
- 限制容器的資源:在運(yùn)行容器時(shí),通過
--memory、--cpus等參數(shù)限制容器的內(nèi)存和CPU使用,防止容器過度占用資源。
docker run -d -p 8080:8080 --memory=512m --cpus=0.5 my-java-app:1.0.0
- 定期更新基礎(chǔ)鏡像和依賴:及時(shí)更新基礎(chǔ)鏡像和項(xiàng)目依賴,修復(fù)已知的安全漏洞。
(三)鏡像版本管理
- 使用有意義的標(biāo)簽:為鏡像設(shè)置有意義的標(biāo)簽,如版本號(hào)、構(gòu)建時(shí)間等,便于識(shí)別和管理不同版本的鏡像。例如,
my-java-app:1.0.0、my-java-app:2.0.0-20250804。 - 清理過期鏡像:定期清理不再使用的鏡像,釋放存儲(chǔ)空間??梢允褂?code>docker image prune命令清理懸空鏡像(沒有標(biāo)簽的鏡像):
docker image prune
也可以通過docker rmi命令刪除指定的鏡像:
docker rmi my-java-app:1.0.0
九、常見問題及解決方法
(一)依賴下載緩慢
在構(gòu)建鏡像時(shí),如果依賴下載緩慢,可以配置國內(nèi)的鏡像源。例如,對(duì)于Maven項(xiàng)目,可以在pom.xml文件中配置阿里云的Maven鏡像:
<repositories>
<repository>
<id>aliyunmaven</id>
<name>阿里云公共倉庫</name>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
也可以在Maven的配置文件settings.xml中配置鏡像源。
(二)端口沖突
在運(yùn)行容器時(shí),如果出現(xiàn)端口沖突的問題,可以修改端口映射,將容器的端口映射到宿主機(jī)的其他空閑端口。例如:
docker run -d -p 8081:8080 my-java-app:1.0.0
將宿主機(jī)的8081端口映射到容器的8080端口。
(三)容器啟動(dòng)后立即退出
如果容器啟動(dòng)后立即退出,可能是應(yīng)用程序啟動(dòng)失敗導(dǎo)致的。可以使用docker logs命令查看容器的日志,排查應(yīng)用程序啟動(dòng)失敗的原因,如配置錯(cuò)誤、依賴缺失等。
(四)鏡像體積過大
如果鏡像體積過大,可以通過多階段構(gòu)建、選擇合適的基礎(chǔ)鏡像、清理不必要的文件等方式進(jìn)行優(yōu)化,如前面在鏡像優(yōu)化部分所介紹的內(nèi)容。
總結(jié)
到此這篇關(guān)于Docker容器Java項(xiàng)目打包與部署的文章就介紹到這了,更多相關(guān)Docker Java項(xiàng)目打包與部署內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java如何根據(jù)用戶請(qǐng)求獲取ip地址并解析省市信息
根據(jù)當(dāng)前用戶本地IP地址,查詢IP地址庫,獲取IP所在的省市信息,目前有多種方式實(shí)現(xiàn)該功能,這篇文章主要給大家介紹了關(guān)于java如何根據(jù)用戶請(qǐng)求獲取ip地址并解析省市信息的相關(guān)資料,需要的朋友可以參考下2023-12-12
springboot對(duì)接第三方微信授權(quán)及獲取用戶的頭像和昵稱等等
這篇文章主要介紹了springboot對(duì)接第三方微信授權(quán)及獲取用戶的頭像和昵稱等等,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
SpringBoot基于Redis實(shí)現(xiàn)token的在線續(xù)期的實(shí)踐
本文主要介紹了使用Redis實(shí)現(xiàn)JWT令牌在線續(xù)期的方案,通過在線續(xù)期token,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-12-12
Spring+MyBatis多數(shù)據(jù)源配置實(shí)現(xiàn)示例
本篇文章主要介紹了Spring+MyBatis多數(shù)據(jù)源配置實(shí)現(xiàn)示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-01-01
JavaScript中棧和隊(duì)列應(yīng)用詳情
這篇文章主要介紹了JavaScript中棧和隊(duì)列應(yīng)用詳情,棧如果用數(shù)組模擬的話是類似于一個(gè)U形桶狀堆??臻g,文章圍繞制圖展開詳細(xì)的內(nèi)容展開更多相關(guān)內(nèi)容,需要的小伙伴可以參考一下2022-06-06
spring?boot應(yīng)用無法啟動(dòng)也沒報(bào)錯(cuò)信息的解決辦法
在使用Spring Boot開發(fā)應(yīng)用程序時(shí),偶爾會(huì)遇到啟動(dòng)不起來的問題,這是一種讓人沮喪的情況,尤其是當(dāng)日志中沒有任何錯(cuò)誤信息時(shí),這篇文章主要介紹了spring?boot應(yīng)用無法啟動(dòng)也沒報(bào)錯(cuò)信息的解決辦法,需要的朋友可以參考下2025-11-11

