搜尋
首頁Javajava教程SpringBoot的實用技巧分享

SpringBoot的實用技巧分享

Oct 15, 2018 pm 01:35 PM
javaspringboot

這篇文章帶給大家的內容是關於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中文網其他相關文章!

陳述
本文轉載於:segmentfault思否。如有侵權,請聯絡admin@php.cn刪除
如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?Mar 17, 2025 pm 05:46 PM

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?Mar 17, 2025 pm 05:45 PM

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?Mar 17, 2025 pm 05:44 PM

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?Mar 17, 2025 pm 05:43 PM

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Mar 17, 2025 pm 05:35 PM

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA

See all articles

熱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尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。