SpringBoot學習筆記

肉食动物123發表於2024-07-17

微服務階段

javaSE:OOP

mySQL:持久化

html+css+js+jquery+框架:檢視,框架不熟練,css不好;

javaweb:獨立開發MVC三層架構的的網站:原始

ssm:框架:簡化了我們的開發流程,配置也開始較為複雜;

war:tomcat執行

spring再簡化:springBoot-jar:內嵌tomcat;微服務架構!

服務越來越多:springcloud!

高內聚,低耦合

微服務(Microservices)——Martin Flower閱讀筆記

整體風格(monolithic style):一個完整應用程式(monolithic application)構建成一個單獨的單元。企業級應用通常被構建成三個主要部分:客戶端使用者介面(由執行在客戶機器上的瀏覽器的 HTML 頁面、Javascript 組成)、資料庫(由許多的表構成一個通用的、相互關聯的資料管理系統)、服務端應用。服務端應用處理 HTTP 請求,執行領域邏輯(domain logic),檢索並更新資料庫中的資料,使用適當的 HTML 檢視傳送給瀏覽器。服務端應用是完整的 ,是一個單獨的的邏輯執行。任何對系統的改變都涉及到重新構建和部署一個新版本的服務端應用程式。(單一應用程式的弊端,可擴充性較差,維護難度較大

微服務架構風格(microservice architectural style):把應用程式構建為一套服務。事實是,服務可以獨立部署和擴充套件,每個服務提供了一個堅實的模組邊界,甚至不同的服務可以用不同的程式語言編寫。它們可以被不同的團隊管理。

微服務風格的特性:

  1. 元件化(Componentization )與服務(Services)

  2. 圍繞業務功能的組織

    不是按照技術構建團隊而是按照業務進行組建,意味著團隊內將由不同技術方向的成員構成,如UI工程師、後端工程師、資料工程師等,而非先前的單一專業。

  3. 產品不是專案:團隊應該負責產品的整個生命週期

  4. 強化終端及弱化通道:微服務的應用致力松耦合和高內聚

  5. 分散治理:不同的需求,不同的業務,不同的微服務,不同的技術,不同的語言,相同的專案。

  6. 分散資料管理:當對概念模式下決心進行分散管理時,微服務也決定著分散資料管理。微服務讓每個服務管理自己的資料庫:無論是相同資料庫的不同例項,或者是不同的資料庫系統。這種方法叫Polyglot Persistence(多種持久化方法)。微服務架構強調服務間事務的協調,並清楚的認識一致性只能是最終一致性以及透過補償運算處理問題。

  7. 基礎設施自動化:微服務的出現使得系統的運維測試工作難度加大,需要對系統的打包釋出測試等環節儘可能的採取自動化手段進行,因此有必要對軟體開發流程中的部分環節採取自動化改進。

  8. 容錯性設計:使用服務作為元件的一個結果在於應用需要有能容忍服務的故障的設計。任務服務可能因為供應商的不可靠而故障,客戶端需要儘可能的最佳化這種場景的響應。跟整體構架相比,這是一個缺點,因為它帶來的額外的複雜性。

    服務可以隨時故障,快速故障檢測,乃至,自動恢復變更非常重要。監控系統可以提供一種早期故障告警系統,讓開發團隊跟進並調查。對於微服務框架來說,這相當重要,因為微服務相互的通訊可能導致緊急意外行為。

  9. 設計改進:決定拆分我們應用的原則是什麼呢?首要的因素,元件可以被獨立替換和更新的,這意味著我們尋找的關鍵在於,我們要想象著重寫一個元件而不影響它們之前的協作關係。事實上,許多的微服務小組給它進一步的預期:服務應該能夠報廢的,而不是要長久的發展的。其次,可代替是模組化開發中的一個特例,它是用模組來應對需要變更的。把元件改成服務,增加了細化釋出計劃的一個機會。

微服務是未來嗎?

微服務構架風格是一個非常重要的想法:一個值得企業應用中認真考慮的東西。

微服務架構的成功依賴於軟體如何拆分成適合的模組。指出不同模組的準確邊界實際上是非常困難的。改良設計要承認邊界的權益困境和因此帶來的易於重構的重要性。

spring Boot

環境:

  • jdk:1.8

  • maven:3.6.1

  • springboot:最新版

  • IDEA

一、第一個SpringBoot程式

1.1 如何建立springboot專案

  1. 方法一:可以在管網配置後直接下載,匯入IDEA開發(Spring Initializr)或者使用aliyun的Cloud Native App Initializer (aliyun.com)來建立新的springboot專案

    注:aliyun目前支援使用java8建立springboot專案,

  2. 方法二:直接使用IDEA建立一個springboot專案(其實和官網類似,一般開發直接在IDEA中建立)

注:如果初學者電腦安裝的是1.8,可以額外安裝jdk17

1.2 Springboot自動裝配原理

  • pom.xml

    • spring-boot-dependencies:核心依賴在父工程中!
    • 我們在寫或者引入一些springboot依賴的時候,不需要指定版本,就是因為有這些版本倉庫
  • 啟動器

    • <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter</artifactId>
      </dependency>
      
    • 啟動器說白了就是springboot的啟動場景

    • 比如spring-boot-starter-web,它就會幫我們自動匯入web環境的所有依賴!

    • springboot會將所有的功能場景都變成一個個的啟動器

    • 我們要使用什麼功能,就只需要找到對應的啟動器就可以了

    • 所有springboot啟動器列表(version2.7.18)Spring Boot Reference Documentation

  • 主程式

    • //程式主入口
      //本身就是spring的一個元件
      //@SpringBootApplication標註這個類是一個springboot的應用
      @SpringBootApplication
      public class SpringBoot17Application {
      
          public static void main(String[] args) {
              SpringApplication.run(SpringBoot17Application.class, args);
          }
      
      }
      
    • 註解:

      • @SpringBootConfiguration:springboot的配置
            @Configuration:spring的配置類
            @Component:說明這也是一個spring的元件
        
      • @EnableAutoConfiguration:自動配置,獲取pom中的全部依賴並匯入
            @AutoConfigurationPackage:自動配置包
                 @Import({AutoConfigurationPackages.Registrar.class}):自動配置`包註冊`
            @Import({AutoConfigurationImportSelector.class}):自動配置匯入選擇器
        
      • //獲取所有的配置
        List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
        
        
      • //獲取候選的配置
        protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        		List<String> configurations = ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader())
        			.getCandidates();
        		Assert.notEmpty(configurations,
        				"No auto configuration classes found in "
        						+ "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you "
        						+ "are using a custom packaging, make sure that file is correct.");
        		return configurations;
        	}
        
      • 需要注意,springboot2和3在這個地方的寫法略微有些不同,上面的是springboot3的程式碼,下滿是2的

      • protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
                List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
                Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
                return configurations;
            }
        
            protected Class<?> getSpringFactoriesLoaderFactoryClass() {
                return EnableAutoConfiguration.class;
            }
        
      • META-INF/spring.factories:自動配置的核心檔案

        • Properties properties = PropertiesLoaderUtils.loadProperties(resource);
          所有資源載入到配置類中!
          

結論:springboot所有自動配置都是在啟動的時候掃描並載入:spring.factories所有的自動配置類都在這裡面,但是不一定生效,要判斷條件是否成立。如果匯入了對應的start,就有對應的啟動器了,有了啟動器,自動裝配就會生效,然後就配置成功。

  1. springboot在啟動的時候,從類路徑下/META-INF/spring.factories獲取指定的值;
  2. 將這些自動配置的類匯入容器,自動配置就會生效,幫程式設計師進行自動配置
  3. 以前我們需要自動配置的東西,現在springboot幫我們做了
  4. 整合JavaEE,解決方案和自動配置的東西都在spring-boot-autoconfigure
  5. 它會把所有需要匯入的元件,以類名的方式返回,這些元件就會被新增到容器中。
  6. 容器中也會存在非常多的xxxAutoConfiguration的檔案(@Bean),就是這些類給容器中匯入了這個場景需要的所有元件,並自動配置,@Configuration
  7. 有了自動配置類,免去了我們手動編寫配置類的需求。

1.3 SpringApplication.Run

  1. SpringApplication.run分析

     public static void main(String[] args) {
            SpringApplication.run(SpringLearningApplication.class, args);
        }
    

    該方法分成兩部分,一部分是SpringApplication的例項化,另一個是run方法的執行。

  2. SpringApplication分析

    這個類主要做了以下四件事情

    • 推斷應用的型別是普通專案還是Web專案
    • 查詢並載入所有可用的初始化器,設定到initializers屬性中
    • 找出所有的應用程式監聽器,設定到listeners屬性中
    • 推斷並設定main方法的定義類,找到執行的主類

    構造器如下:

    public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
            this.sources = new LinkedHashSet();
            this.bannerMode = Mode.CONSOLE;
            this.logStartupInfo = true;
            this.addCommandLineProperties = true;
            this.addConversionService = true;
            this.headless = true;
            this.registerShutdownHook = true;
            this.additionalProfiles = Collections.emptySet();
            this.isCustomEnvironment = false;
            this.lazyInitialization = false;
            this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
            this.applicationStartup = ApplicationStartup.DEFAULT;
            this.resourceLoader = resourceLoader;
            Assert.notNull(primarySources, "PrimarySources must not be null");
            this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
            this.webApplicationType = WebApplicationType.deduceFromClasspath();
            this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
            this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
            this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
            this.mainApplicationClass = this.deduceMainApplicationClass();
        }
    

Docker:程序

關於Springboot,談談個人理解:

  • 自動裝配
  • run()

全面接管SpringMVC的配置

1.4 SpringBoot:配置檔案及自動裝配原理

  1. 配置檔案

    SpringBoot使用一個全域性配置檔案,配置檔名稱是固定的(application)

    • application.properties(等號取值)
      • 語法結構:key=value
    • application.yml(冒號取值,一定注意空格)
      • 語法結構:key:空格 value

    配置檔案的作用:修改SpringBoot自動裝配的預設值,因為SpringBoot在底層都給我們自動配置好了;

  2. YAML

    標記語言

    • 以前的配置檔案,大多數使用xml來配置;比如一個簡單的埠配置,我們來對比下yaml和xml

    yaml配置

    • server:
        port: 8081
      

    xml配置

    • <server>
          <port>8081</port>
      </server>
      

    YAML基本語法

    • spring.application.name=springboot-02-config
      # 官方配置太多了,需要了解原理:一通百通
      # properties智慧儲存鍵值對
      
    • # 注意,yaml檔案對空格的要求十分嚴格,一旦空格有誤容易導致上下級屬性關係錯位
      # 可以注入到配置類中
      
      # 普通的key-value
      server:
        port: 8081
      
      # 還可以儲存物件
      student:
        name: wut
        age: 25
      
      # 或者將物件寫在行內
      
      student1: {name: wut,age: 24}
      
      # 甚至可以儲存陣列
      pets:
        - cat
        - dog
        - pig
      
      # 陣列也可以這麼寫
      pets1: [cat,dog,pig]
      

  3. 鬆散繫結

    ​ 使用@ConfigurationProperties(prefix = "xxx")註解可以進行鬆散繫結,採取駝峰命名規則就可以實現前後端賦值,但是注意如果是欄位上採取@Value("xx")這種針對某個單一欄位進行輔助,沒有鬆散繫結,需要欄位名一致才能實現。

  4. JSR303資料校驗

    • 相當於在賦值的時候新增一層過濾器,對賦值內容進行校驗,有點類似於前端的內容檢查。

    • 開啟方法是在類上新增@Validated註解

    • @ConfigurationProperties @Value
      功能 批次注入配置檔案中的屬性 一個個指定程式碼中引數取值
      鬆散繫結(鬆散語法) 支援 不支援
      SpEl(Spring Expression Language) 不支援 支援
      JSR303資料校驗 支援 不支援
      複雜型別封裝 支援 不支援

注:

  1. ​ 在使用@ConfigurationProperties(prefix = "xxx")註解時,會出現這樣的東西,原因是“Spring Boot配置註解執行器沒有配置”。配置註解執行器配置完成後,當執行類中已經定義了物件和該物件的欄位後,在配置檔案中對該類賦值時,便會非常方便的彈出提示資訊。但不配置也不影響系統執行。解決這個問題的方法如下:

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
                <optional>true</optional>
    </dependency>
    
  2. 這個地方有一個需要注意的地方,如果當前springboot版本為2.3.0以上,則需要手動在springboot的啟動中引入相關的校驗包

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-validation</artifactId>
     </dependency>
    

    ​ 另外注意一點springboot3不再支援使用原來的javax.validatio,需要使用jakarta.validation,這一點是springboot2和springboot3之間的區別。

  3. 多環境配置以及配置檔案位置

    • 配置環境優先順序,springboot專案一共有四個地方可以配置相關環境,分別是

      1. optional:classpath:/config/
      2. optional:file:./config/*/
      3. optional:classpath:custom-config/
      4. optional:file:./custom-config/

    • 黃色優先順序最高,紅色其次,藍色第三,綠色第四

    • 多環境配置實現:透過spring.profiles.active指定生效檔案,如下所示:

      • spring:
          profiles:
            active: dev
        
    • 或者透過yaml實現多配置模組

      • spring:
          profiles:
            active: dev
        
        
        ---
        server:
          port: 8082
        spring:
          config:
            activate:
              on-profile: dev
        
        
        ---
        server:
          port: 8083
        spring:
          config:
            activate:
              on-profile: test
        
      • 此處需要注意不同版本的書寫格式不太一樣

相關文章