簡體   English   中英

Spring Boot 2.1和Java 11中的Bean生命周期

[英]Bean lifecycle in Spring Boot 2.1 and Java 11

我的項目正在從使用Java 8的Spring Boot 2.0.4遷移到使用Java 11的Spring Boot 2.1.0。當應用程序使用Spring Boot 2.0.4和Java 8構建並在Docker / Docker Compose中運行時,@ @PostConstruct -annotated方法被調用,但在轉移到Spring Boot 2.1.0和Java 11之后,不再調用@PreDestroy -annotated方法。

我試圖從注釋切換到實施InitializingBeanDisposableBean描述在這里 ,但DisposableBean.destroy方法不叫。

我還嘗試將依賴項添加到javax.annotation-api版本1.3.2,結果相同。

如何重現:

使用生命周期bean創建一個最小的Spring應用程序:

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Component
public class Life implements InitializingBean, DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("--- Life.shutdown");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("--- Life.startup");
    }
}

從目標子文件夾啟動Spring應用程序:

cd target
java -jar demo-0.0.1-SNAPSHOT.jar

使用Ctrl + C停止應用程序時,將調用DisposableBean.destroy。

返回父文件夾:

cd ..

使用Maven啟動Spring應用程序:

mvn spring-boot:run

使用Ctrl + C停止應用程序時,將調用DisposableBean.destroy。

Dockerfile:

FROM openjdk:11.0.1-jre-slim
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT java -jar /app.jar

構建,運行和停止Docker鏡像:

docker build -t demo .
docker run -p 8080:8080 demo
docker ps
docker stats 3ca5b804ab13
docker stop 3ca5b804ab13
docker logs 3ca5b804ab13

使用docker stop停止應用程序時,不會調用DisposableBean.destroy。

泊塢窗,compose.yml:

demo:
  image: demo
  ports:
  - '8080:8080'

使用Docker Compose運行Docker鏡像(模擬OpenShift):

docker-compose up
docker-compose down
demo_demo_1 exited with code 137

使用docker-compose down停止應用程序時,不會調用DisposableBean.destroy。

我懷疑Docker在發出SIGKILL之前正在嘗試使用SIGTERM,因為在容器被殺之前有10秒的延遲。

有很多地方設置可能出錯。 首先,我建議確定java / spring部分是否存在某些問題,或者是與docker / environment相關的問題。 從這個問題看起來它與java有關,但實際上我懷疑它不是在java / spring中。

所以, mvn spring-boot:run按預期工作,我看到你將spring boot應用程序打包為jar(app.jar)可能帶有spring boot插件。 這也是一個可能出錯的地方,因為spring boot使用特殊的類加載器來加載運行時的東西。

因此,為了完全消除“java / spring”部分導航到target目錄並運行java -jar app.jar (確保本地機器上安裝了java 11)。 如果它不起作用 - 調查java / spring部分,否則繼續使用docker部分。

應用程序可能會按預期工作。

現在,至於docker設置。 運行docker compose並看到它失敗后,

您可以使用以下命令:

docker ps -a // -a flag to see container ids of containers that were stopped for whatever reason as well.

現在,找到退出的java進程的Id並檢查其日志:

docker logs <ID_OF_THE_EXTED_CONTAINER_GOES_HERE> 

現在很可能是應用程序上下文無法啟動(可能是與網絡相關的問題或其他問題,這里很難說沒有看到實際的日志),因此也就是問題。

另一個可能的問題是應用程序“太重”(我的意思是它超過了對docker容器施加的一些配額)。

您可以運行docker stats <CONTAINER_ID>命令以實時查看其內存/ CPU使用情況,或從應用程序中收集指標。

我想我找到了解決方案(在這個博客條目中 ):在Dockerfile中使用exec表單而不是shell表單,這樣Docker發出的SIGTERM就會遇到java進程而不是bash進程(它不會將信號轉發給任何子進程) )。

  • Shell表單(使用/ bin / sh -c shell執行): ENTRYPOINT java -jar /app.jar
  • Exec表單(沒有shell執行): ENTRYPOINT ["java", "-jar", "/app.jar"]

轉換 ArrayList 列表的最佳方法是什么<object>到自定義 object java11 Spring 引導 2.1<div id="text_translate"><p> 我有 ArrayList 對象列表,其中對象可以是文本、BigDecimal、Long</p><pre> List&lt;Object&gt; data = { {"date","prize1","cardsNumers","cardObtained","totalCards","anotherPrize"}, {"2020-05-01",435345.67,43,56,67,345345345}, {"2020-03-01",45656.2,34,67,23,456456}, {"2020-02-01",56565,34,56,67,878987} }</pre><p> arrayList 中的第 1、2、3 等對象是第 0 個 arraylist 中提到的每個字段的值。 在如下表中,</p><p> <a href="https://i.stack.imgur.com/Tmdw2.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Tmdw2.png" alt="在此處輸入圖像描述"></a></p><p> 我想從上面獲取每個文件的總和並分配給下面自定義 Object 的同一字段,</p><pre> public class SumObject { private Date date; private BigDecimal sumPrize1; private BigDecimal sumCardsNumers; private long sumCardObtained; private long sumTotalCards; private long sumAnotherPrize; }</pre><p> 我通過遍歷 List 中的 arrayList 來實現這一點,並通過 get(index) 方法獲取值。 但我想知道是否有任何其他好的方法可以做到這一點。</p><p> 如果有人有任何建議,請發布答案或給我一個我可以閱讀的文件的方向。</p><p> 提前致謝。</p></div></object>

[英]what would be best way to convert List of ArrayList<Object> to a custom object java11 Spring boot 2.1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

相關問題 Bean生命周期管理Spring Boot 從Spring Boot 2.0.5 / Java 8遷移后,Spring Boot 2.1 / Java 11應用程序無法識別突出字符 Spring Boot 2.1 中的數據源 bean 覆蓋 找不到 Spring Boot 2.1 EntityManagerFactory Bean 轉換 ArrayList 列表的最佳方法是什么<object>到自定義 object java11 Spring 引導 2.1<div id="text_translate"><p> 我有 ArrayList 對象列表,其中對象可以是文本、BigDecimal、Long</p><pre> List&lt;Object&gt; data = { {"date","prize1","cardsNumers","cardObtained","totalCards","anotherPrize"}, {"2020-05-01",435345.67,43,56,67,345345345}, {"2020-03-01",45656.2,34,67,23,456456}, {"2020-02-01",56565,34,56,67,878987} }</pre><p> arrayList 中的第 1、2、3 等對象是第 0 個 arraylist 中提到的每個字段的值。 在如下表中,</p><p> <a href="https://i.stack.imgur.com/Tmdw2.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Tmdw2.png" alt="在此處輸入圖像描述"></a></p><p> 我想從上面獲取每個文件的總和並分配給下面自定義 Object 的同一字段,</p><pre> public class SumObject { private Date date; private BigDecimal sumPrize1; private BigDecimal sumCardsNumers; private long sumCardObtained; private long sumTotalCards; private long sumAnotherPrize; }</pre><p> 我通過遍歷 List 中的 arrayList 來實現這一點,並通過 get(index) 方法獲取值。 但我想知道是否有任何其他好的方法可以做到這一點。</p><p> 如果有人有任何建議,請發布答案或給我一個我可以閱讀的文件的方向。</p><p> 提前致謝。</p></div></object> 帶有 Java 11 的 Spring Boot 2.1:無法解析持久性單元根 URL 使用嵌套的TestConfiguration覆蓋Spring Boot 2.1 Slice測試中的bean Spring Boot 2.1 bean 覆蓋與主要 春豆的生命周期是什么? Spring 引導中的 PersistenceContext 生命周期
 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM