首頁 Java java教程 SpringBoot的實用技巧分享

SpringBoot的實用技巧分享

Oct 15, 2018 pm 01:35 PM
java springboot

這篇文章帶給大家的內容是關於SpringBoot的實用技巧分享,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

前言

最近分享的一些原始碼、框架設計的東西。我發現大家熱情不是特別高,想想大多數應該還是正兒八經寫代碼的居多;這次就分享一點接地氣的: SpringBoot 使用中的一些小技巧。

不算是多高大上的東西,但都還蠻有用。

屏蔽外部依賴

第一個是屏蔽外部依賴,什麼意思呢?

例如大家日常開發時候有沒有這樣的煩惱:

專案是基於 SpringCloud 或是 dubbo 這樣的分散式服務,你需要依賴許多基礎服務。

比如說某個訂單號碼的產生、取得使用者資訊等。

由於服務拆分,這些功能都是在其他應用中以介面的形式提供,單測還好我還可以利用 Mock 把它屏蔽掉。

但如果自己想把應用程式啟動起來同時把自己相關的程式碼跑一遍呢?

通常有幾種做法:

  • 本機把所有的服務都啟動起來。

  • 把註冊中心換成開發環境,依賴開發環境的服務。

  • 直接把程式碼推送到開發環境自測。

看起來三種都可以,以前我也是這樣幹的。但還是有幾個小問題:

  • 本地啟動有可能服務很多,全部起來電腦能不能撐住還兩說,萬一服務有問題就進行不下去了。

  • 依賴開發環境的前提是網路打通,還有一個問題就是開發環境程式碼很不穩定很大可能會影響你的測試。

  • 推送到開發環境應該是比較可靠的方案,但如果想除錯只有日誌大法,沒有本地 debug 的效率高效。

那要如何解決問題呢?既可以在本地調試也不用啟動其他服務。

其實也可以利用單測的做法,把其他外部依賴 Mock 掉就行了。

大致的流程分為以下幾步:

  • SpringBoot 啟動之後在Spring 中找出你需要屏蔽的那個API 的bean(通常情況下這個介面都是交給Spring 管理的)。

  • 手動從 bean 容器中刪除該 bean。

  • 重新建立一個該 API 的對象,只不過是透過 Mock 出來的。

  • 再手動註冊進 bean 容器中。

以下面這段程式碼為例:

    @Override
    public BaseResponse<ordernoresvo> getUserByHystrix(@RequestBody UserReqVO userReqVO) {

        OrderNoReqVO vo = new OrderNoReqVO();
        vo.setAppId(123L);
        vo.setReqNo(userReqVO.getReqNo());
        BaseResponse<ordernoresvo> orderNo = orderServiceClient.getOrderNo(vo);
        return orderNo;
    }</ordernoresvo></ordernoresvo>
登入後複製
這是一個 SpringCloud 應用程式。

它依賴 orderServiceClient 取得一個訂單號碼。

其中的 orderServiceClient 就是一個外部 API,也是被 Spring 所管理。

取代原有的 Bean

下一步就是替換原有的 Bean。

@Component
public class OrderMockServiceConfig implements CommandLineRunner {

    private final static Logger logger = LoggerFactory.getLogger(OrderMockServiceConfig.class);

    @Autowired
    private ApplicationContext applicationContext;

    @Value("${excute.env}")
    private String env;

    @Override
    public void run(String... strings) throws Exception {

        // 非本地环境不做处理
        if ("dev".equals(env) || "test".equals(env) || "pro".equals(env)) {
            return;
        }

        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();

        OrderServiceClient orderServiceClient = defaultListableBeanFactory.getBean(OrderServiceClient.class);
        logger.info("======orderServiceClient {}=====", orderServiceClient.getClass());

        defaultListableBeanFactory.removeBeanDefinition(OrderServiceClient.class.getCanonicalName());

        OrderServiceClient mockOrderApi = PowerMockito.mock(OrderServiceClient.class,
                invocationOnMock -> BaseResponse.createSuccess(DateUtil.getLongTime() + "", "mock orderNo success"));

        defaultListableBeanFactory.registerSingleton(OrderServiceClient.class.getCanonicalName(), mockOrderApi);

        logger.info("======mockOrderApi {}=====", mockOrderApi.getClass());
    }
}
登入後複製

其中實作了 CommandLineRunner 接口,可以在 Spring 容器初始化完成之後呼叫 run() 方法。

程式碼非常簡單,簡單來說先判斷下是什麼環境,畢竟除開本地環境其餘的都是需要真正呼叫遠端服務的。

之後就是要取得 bean 然後手動刪除掉。

關鍵的步驟:

OrderServiceClient mockOrderApi = PowerMockito.mock(OrderServiceClient.class,
                invocationOnMock -> BaseResponse.createSuccess(DateUtil.getLongTime() + "", "mock orderNo success"));

defaultListableBeanFactory.registerSingleton(OrderServiceClient.class.getCanonicalName(), mockOrderApi);
登入後複製

建立了一個新的 OrderServiceClient 物件並手動註冊進了 Spring 容器中。

第一段程式碼使用的是 PowerMockito.mock 的 API,他可以建立一個代理對象,讓所有呼叫 OrderServiceClient 的方法都會做預設的回傳。

BaseResponse.createSuccess(DateUtil.getLongTime() + "", "mock orderNo success"))
登入後複製

測試一下,當我們沒有替換時呼叫剛才那個介面且本機也沒有啟動OrderService

SpringBoot的實用技巧分享

##因為沒有配置fallback 所以會報錯,表示找不到這個服務。

替換掉 bean 時:

SpringBoot的實用技巧分享

再次要求沒有報錯,並且獲得了我們預設的回傳。

SpringBoot的實用技巧分享

透過日誌也會發現

OrderServiceClient 最後已經被Mock 代理程式了,並不會去調用真正的方法。

配置加密

下一個則是配置加密,這應該算是一個基本功能。

例如我們設定檔中的一些帳號和密碼,都應該是密文保存的。

因此這次使用了一個開源元件來實現加密與解密,並且對

SpringBoot 非常友好只需要幾段程式碼即可完成。

  • 首先根据加密密码将需要加密的配置加密为密文。

  • 替换原本明文保存的配置。

  • 再使用时进行解密。

使用该包也只需要引入一个依赖即可:

<dependency>
    <groupid>com.github.ulisesbocchio</groupid>
    <artifactid>jasypt-spring-boot-starter</artifactid>
    <version>1.14</version>
</dependency>
登入後複製

同时写一个单测根据密码生成密文,密码也可保存在配置文件中:

jasypt.encryptor.password=123456
登入後複製

接着在单测中生成密文。

    @Autowired
    private StringEncryptor encryptor;

    @Test
    public void getPass() {
        String name = encryptor.encrypt("userName");
        String password = encryptor.encrypt("password");
        System.out.println(name + "----------------");
        System.out.println(password + "----------------");

    }
登入後複製

之后只需要使用密文就行。

由于我这里是对数据库用户名和密码加密,所以还得有一个解密的过程。

利用 Spring Bean 的一个增强接口即可实现:

@Component
public class DataSourceProcess implements BeanPostProcessor {


    @Autowired
    private StringEncryptor encryptor;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        if (bean instanceof DataSourceProperties){
            DataSourceProperties dataSourceProperties = (DataSourceProperties) bean;
            dataSourceProperties.setUsername(encryptor.decrypt(dataSourceProperties.getUsername())) ;
            dataSourceProperties.setPassword(encryptor.decrypt(dataSourceProperties.getPassword()));
            return dataSourceProperties ;
        }

        return bean;
    }
}
登入後複製

这样就可以在真正使用时还原为明文。

同时也可以在启动命令中配置刚才的密码:

java -Djasypt.encryptor.password=password -jar target/jasypt-spring-boot-demo-0.0.1-SNAPSHOT.jar
登入後複製

以上是SpringBoot的實用技巧分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java 中的完美數 Java 中的完美數 Aug 30, 2024 pm 04:28 PM

Java 完美數指南。這裡我們討論定義,如何在 Java 中檢查完美數?

Java 中的隨機數產生器 Java 中的隨機數產生器 Aug 30, 2024 pm 04:27 PM

Java 隨機數產生器指南。在這裡,我們透過範例討論 Java 中的函數,並透過範例討論兩個不同的生成器。

Java中的Weka Java中的Weka Aug 30, 2024 pm 04:28 PM

Java 版 Weka 指南。這裡我們透過範例討論簡介、如何使用 weka java、平台類型和優點。

Java 中的史密斯數 Java 中的史密斯數 Aug 30, 2024 pm 04:28 PM

Java 史密斯數指南。這裡我們討論定義,如何在Java中檢查史密斯號?帶有程式碼實現的範例。

Java Spring 面試題 Java Spring 面試題 Aug 30, 2024 pm 04:29 PM

在本文中,我們保留了最常被問到的 Java Spring 面試問題及其詳細答案。這樣你就可以順利通過面試。

突破或從Java 8流返回? 突破或從Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

Java 中的時間戳至今 Java 中的時間戳至今 Aug 30, 2024 pm 04:28 PM

Java 中的時間戳記到日期指南。這裡我們也結合範例討論了介紹以及如何在java中將時間戳記轉換為日期。

創造未來:零基礎的 Java 編程 創造未來:零基礎的 Java 編程 Oct 13, 2024 pm 01:32 PM

Java是熱門程式語言,適合初學者和經驗豐富的開發者學習。本教學從基礎概念出發,逐步深入解說進階主題。安裝Java開發工具包後,可透過建立簡單的「Hello,World!」程式來實踐程式設計。理解程式碼後,使用命令提示字元編譯並執行程序,控制台上將輸出「Hello,World!」。學習Java開啟了程式設計之旅,隨著掌握程度加深,可創建更複雜的應用程式。

See all articles