日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

企业级spring-boot案例-自定义Spring Boot Starter

發布時間:2023/12/20 javascript 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 企业级spring-boot案例-自定义Spring Boot Starter 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1. 未使用Spring Boot Starter前的情況
    • 2. Spring Boot Starter簡介
      • 2.1 什么是Spring Boot Starter(啟動器)
      • 2.2 Starter 模塊整體結構
      • 2.3 Spring 官方提供的 Starter 和 Starter 命名規范
    • 3. 自定義Spring Boot Starter
      • 3.1 根據 starter 命名規范創建一個 spring boot 項目
      • 3.2 在 pom.xml 文件中引入依賴
      • 3.3 編寫`ConfigInfo.java`、`ConfigService.java`、 `ConfigServiceImpl.java`
      • 3.4 編寫ConfigProperties.java
      • 3.5 編寫ConfigAutoConfiguration.java
      • 3.6 編寫spring.factories
      • 3.7 發布自定義 starter
      • 3.8 測試自定義 starter
        • 3.8.1 添加config-spring-boot-starter依賴
        • 3.8.2 配置application.yml
        • 3.8.3 編寫 ConfigInfoController.java
        • 3.8.4 啟動測試
    • 4. Spring Boot Starter原理
      • 4.1 自動配置原理
        • 4.1.1 自動配置類的獲取與注入
        • 4.1.2 自動配置的過程
      • 4.2 Spring Boot自動配置使用總結

企業級spring-boot案例系列文章上線了,涵蓋了大部分企業級的spring-boot使用場景,會不定期進行更新,企業級spring-boot案例源碼地址:https://gitee.com/JourWon/spring-boot-example,歡迎各位大佬一起學習和指正

1. 未使用Spring Boot Starter前的情況

在沒有 starter 之前,假如我想要在 Spring 中使用 jpa,那我可能需要做以下操作:

  • 在 Maven 中引入使用的數據庫的依賴(即 JDBC 的 jar)
  • 引入 jpa 的依賴
  • 在 xxx.xml 中配置一些屬性信息
  • 反復的調試直到可以正常運行
  • 需要注意的是,上面的操作在我們每次新建一個需要用到 jpa 的項目的時候都需要重復的做一次

    但在 Spring Boot 中,一切因為 Starter 變得簡單

  • 在 pom 文件中引入 spring-boot-starter-data-jpa
  • 在 .properties 文件中配置參數
  • 通過上面兩個步驟,配置自動生效,具體生效的 bean 是 JpaRepositoriesAutoConfiguration,自動配置類的名字都有一個特點,叫做 xxxAutoConfiguration。

    這就是使用 Spring 框架開發項目帶來的一些的問題:

    • 依賴導入問題: 每個項目都需要來單獨維護自己所依賴的jar包,在項目中使用到什么功能就需要引入什么樣的依賴。手動導入依賴容易出錯,且無法統一集中管理
    • 配置繁瑣: 在引入依賴之后需要做繁雜的配置,并且這些配置是每個項目來說都是必要的,例如web.xml配置(Listener配置、Filter配置、Servlet配置)、log4j配置、數據庫連接池配置等等。這些配置重復且繁雜,在不同的項目中需要進行多次重復開發,這在很大程度上降低了我們的開發效率

    而在 Spring Boot 出現之后,它為我們提供了一個強大的功能來解決上述的兩個痛點,這就是 Spring Boot 的 starters(啟動器)。

    2. Spring Boot Starter簡介

    2.1 什么是Spring Boot Starter(啟動器)

    Spring Boot 通過將我們常用的功能抽取出來,做成的一系列啟動器,這些啟動器幫我們導入了實現各個功能所需要依賴的全部組件,我們只需要在項目中引入這些 starters,需要的依賴就會全部被導入進來,并且我們通過【約定大于配置】的方式,拋棄繁雜的配置,僅需要通過配置文件來進行少量的配置就可以使用相應的功能。

    starter 的實現:雖然不同的 starter 實現起來各有差異,但是他們基本上都會使用到兩個相同的內容:ConfigurationProperties 和 AutoConfiguration。因為 Spring Boot 堅信 “約定大于配置” 這一理念,所以我們使用 ConfigurationProperties 來保存我們的配置,并且這些配置都可以有一個默認值,即在我們沒有主動覆寫原始配置的情況下,默認值就會生效,這在很多情況下是非常有用的。除此之外,starter 的 ConfigurationProperties 還使得所有的配置屬性被聚集到一個文件中(一般在 resources 目錄下的 application.properties),這樣我們就告別了 Spring 項目中眾多的 XML 配置。

    2.2 Starter 模塊整體結構

    starter的整體實現邏輯主要由兩個基本部分組成:

    xxxAutoConfiguration:自動配置類,對某個場景下需要使用到的一些組件進行自動注入,并利用xxxProperties類來進行組件相關配置

    xxxProperties:某個場景下所有可配置屬性的集成,在配置文件中配置可以進行屬性值的覆蓋,按照SpringBoot官方的定義,Starer的作用就是依賴聚合,因此直接在starter內部去進行代碼實現是不符合規定的,starter應該只起到依賴導入的作用,而具體的代碼實現應該交給其他模塊來實現,然后在starter中去引用該模塊即可,因此整體的starter的構成應該如下圖所示:

    可見starter模塊依賴了兩部分,一部分是一些常用依賴,另一部分就是對自動配置模塊的依賴,而xxxAutoConfiguration與xxxProperties的具體實現,都封裝在自動配置模塊中,starter實際是通過該模塊來對外提供相應的功能。

    2.3 Spring 官方提供的 Starter 和 Starter 命名規范

    SpringBoot 提供了非常多的 Starter,下面列出常用的幾個:

    序號名稱功能
    1spring-boot-starter-web支持 Web 開發,包括 Tomcat 和 spring-webmvc
    2spring-boot-starter-redis支持 Redis 鍵值存儲數據庫,包括 spring-redis
    3spring-boot-starter-test支持常規的測試依賴,包括 JUnit、Hamcrest、Mockito 以及 spring-test 模塊
    4spring-boot-starter-aop支持面向切面的編程即 AOP,包括 spring-aop 和 AspectJ
    5spring-boot-starter-data-elasticsearch支持 ElasticSearch 搜索和分析引擎,包括 spring-data-elasticsearch
    6spring-boot-starter-jdbc支持JDBC數據庫
    7spring-boot-starter-data-jpa支持 JPA ,包括 spring-data-jpa、spring-orm、Hibernate

    可以看到這些 Starter 的名稱都是以 spring-boot-starter 為開頭,后面跟著具體的模塊名,所有官方的 Starter 遵循相似的命名模式。

    根據約定,Spring Boot官方的starter命名要定義為spring-boot-starter-*,自定義或者說第三方的要命名為thirdpartyproject-spring-boot-starter

    • 官方命名空間
      • 前綴:spring-boot-starter-
      • 模式:spring-boot-starter-模塊名
      • 舉例:spring-boot-starter-web、spring-boot-starter-actuator、spring-boot-starter-jdbc
    • 自定義命名空間
      • 后綴:-spring-boot-starter
      • 模式:模塊-spring-boot-starter
      • 舉例:mybatis-spring-boot-starter

    3. 自定義Spring Boot Starter

    如果你想要自己創建一個 starter,那么基本上包含以下幾步

    3.1 根據 starter 命名規范創建一個 spring boot 項目

    創建一個名為config-spring-boot-starter的 spring boot 項目

    3.2 在 pom.xml 文件中引入依賴

    <!-- 自動配置依賴 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId> </dependency><!-- 將被@ConfigurationProperties注解的類的屬性注入到元數據 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional> </dependency><!-- starter非必須依賴,使用到了可以添加 --> <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional> </dependency>

    3.3 編寫ConfigInfo.java、ConfigService.java、 ConfigServiceImpl.java

    ConfigInfo 配置信息類,用于封裝配置信息。

    @Data @Builder public class ConfigInfo implements Serializable {private static final long serialVersionUID = -2878523532668902073L;/*** ID*/private String id;/*** IP地址*/private String ip;}

    ConfigService 示例業務接口,這里我們定義了一個configInfo接口,用于獲取配置信息。

    public interface ConfigService {/*** 獲取配置信息** @return {@link ConfigInfo}*/ConfigInfo configInfo();}

    ConfigServiceImpl 業務邏輯實現類,用于實現功能。

    public class ConfigServiceImpl implements ConfigService {/*** ID*/private String id;/*** ip*/private String ip;/*** 構造函數** @param id ID* @param ip IP*/public ConfigServiceImpl(String id, String ip) {this.id = id;this.ip = ip;}/*** 獲取配置信息** @return {@link ConfigInfo}*/@Overridepublic ConfigInfo configInfo() {return ConfigInfo.builder().id(this.id).ip(this.ip).build();}}

    3.4 編寫ConfigProperties.java

    創建一個配置文件讀取類 ConfigurationProperties 用于保存配置信息(如果你的項目不使用配置信息則可以跳過這一步,不過這種情況非常少見)

    @ConfigurationProperties注解使開發人員可以輕松地將整個文件.properties和yml文件映射到一個對象中。編寫Properties,應使用唯一的名稱空間。不要使用Spring Boot的名稱空間(如server,management,spring等)。所以應在所有配置鍵前面加上自己的名稱空間。如我們這里使用的是com.jourwon.config作為配置名稱空間。

    @Data @ConfigurationProperties(value = "com.jourwon.config") public class ConfigProperties {/*** ID標識*/private String id;/*** IP地址*/private String ip;}

    3.5 編寫ConfigAutoConfiguration.java

    創建一個 AutoConfiguration,編寫帶有@Configuration的配置類,并添加@EnableConfigurationProperties注解,@EnableConfigurationProperties作用是為了使@ConfigurationProperties注解的類生效。

    @Slf4j @Configuration @EnableConfigurationProperties(value = ConfigProperties.class) public class ConfigAutoConfiguration {@Resourceprivate ConfigProperties properties;/*** 配置ExampleService** @return {@link ConfigService}*/@Bean@ConditionalOnMissingBeanpublic ConfigService configService() {log.info("Config ConfigService Start...");ConfigService service = new ConfigServiceImpl(properties.getId(), properties.getIp());log.info("Config ConfigService End.");return service;}}

    3.6 編寫spring.factories

    在resources/META-INF/下創建spring.factories文件,并且把上一步創建的AutoConfiguration類加入 spring.factories 配置文件中

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.jourwon.spring.boot.config.ConfigAutoConfiguration

    3.7 發布自定義 starter

    在自定義 starter 項目根目錄執行 mvn install 進行打包安裝

    3.8 測試自定義 starter

    3.8.1 添加config-spring-boot-starter依賴

    <properties><config-spring-boot-starter.version>1.0.0</config-spring-boot-starter.version> </properties><dependencies><dependency><groupId>com.jourwon.spring.boot</groupId><artifactId>config-spring-boot-starter</artifactId><version>${config-spring-boot-starter.version}</version></dependency><!-- spring-boot-starter-web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency> </dependencies>

    3.8.2 配置application.yml

    IDE 提示

    在使用官方starter的時候,我們可以發現IDE可以進行提示

    在application.yml配置文件添加如下配置

    # 自定義starter相關配置 com:jourwon:config:id: 23145fdb-7427-42d1-ae29-a67f5be30d02ip: 127.0.0.1

    3.8.3 編寫 ConfigInfoController.java

    @RestController public class ConfigInfoController {@Resourceprivate ConfigService configService;@GetMapping("/configInfo")public String configInfo() {return JSON.toJSONString(configService.configInfo());}}

    3.8.4 啟動測試

    打開瀏覽器,輸入 http://127.0.0.1:8080/configInfo ,你將會看到我們配置的內容。

    4. Spring Boot Starter原理

    首先說說原理,我們知道使用一個公用的starter的時候,只需要將相應的依賴添加的Maven的配置文件當中即可,免去了自己需要引用很多依賴類,并且SpringBoot會自動進行類的自動配置。

    在導入的starter之后,SpringBoot主要幫我們完成了兩件事情:

    • 相關組件的自動導入
    • 相關組件的自動配置

    這兩件事情統一稱為SpringBoot的自動配置

    那么 SpringBoot 是如何知道要實例化哪些類,并進行自動配置的呢? 下面簡單說一下。

    首先,SpringBoot 在啟動時會去依賴的starter包中尋找 resources/META-INF/spring.factories文件,然后根據文件中配置的Jar包去掃描項目所依賴的Jar包,這類似于 Java 的 SPI 機制。

    第二步,根據 spring.factories配置加載AutoConfigure類。

    最后,根據 @Conditional注解的條件,進行自動配置并將Bean注入Spring Context 上下文當中。

    我們也可以使用@ImportAutoConfiguration({MyServiceAutoConfiguration.class}) 指定自動配置哪些類。

    4.1 自動配置原理

    4.1.1 自動配置類的獲取與注入

    我們從主程序入口來探索一下整個過程的原理:

    //標注這個類是一個springboot的應用 @SpringBootApplication public class CommunityApplication {public static void main(String[] args) {//將springboot應用啟動SpringApplication.run(CommunityApplication.class, args);} }

    @SpringBootApplication注解內部結構如下圖所示:

    AutoConfigurationImportSelector :重點看該類中重寫的selectImports方法,看下它返回的字符串數組是如何得來的:

    我們可以去到上邊提到的spring.factories文件中去看一下,找到spring官方提供的spring-boot-autoconfigure包,在其下去找一下該文件:

    可以看到這個就是SpringBoot官方為我們提供的所有自動配置類的候選列表。我們可以在其中找到一個我們比較熟悉的自動配置類去看一下它內部的實現:

    可以看到這些一個個的都是JavaConfig配置類,而且都通過@Bean注解向容器中注入了一些Bean

    結論:

    • SpringBoot在啟動的時候從類路徑下的META-INF/spring.factories中獲取EnableAutoConfiguration指定的所有自動配置類的全限定類名
    • 將這些自動配置類導入容器,自動配置類就生效,幫我們進行自動配置工作;
    • 整個J2EE的整體解決方案和自動配置都在spring-boot-autoconfigure的jar包中;
    • 它會給容器中導入非常多的自動配置類 (xxxAutoConfiguration), 就是給容器中導入這個場景需要的所有組件,并配置好這些組件 ;
    • 有了自動配置類,免去了我們手動編寫配置注入功能組件等的工作;

    4.1.2 自動配置的過程

    自動配置類被注入到容器當中后,會幫我們進行組件的自動配置和自動注入的工作,我們以HttpEncodingAutoConfiguration(Http編碼自動配置)為例解釋這個過程:

    首先我們先看下SpringBoot中配置文件與POJO類之間映射的方法,這是進行自動配置的基礎。

    配置集中化管理:SpringBoot中所有可配置項都集中在一個文件中(application.yml),這個文件中的配置通過@ConfigurationProperties注解來與我們程序內部定義的POJO類來產生關聯,這些POJO類統一命名為xxxProperties,并且這些xxxProperties類中各個屬性字段都有自己的默認值,這也是SpringBoot約定大于配置理念的體現,盡可能減少用戶做選擇的次數,但同時又不失靈活性。只要我們想,配置文件中的配置隨時可以覆蓋默認值。

    之后,通過配合@EnableConfigurationProperties注解,就可以自動將與配置文件綁定好的這個類注入到容器中供我們使用。

    自動配置類的工作流程:

    • 根據限定的條件向容器中注入組件
    • 使用xxxProperties對注入的組件的相關屬性進行配置
    //表示這是一個配置類,和以前編寫的配置文件一樣,也可以給容器中添加組件; @Configuration//將與配置文件綁定好的某個類注入到容器中,使其生效 //進入這個HttpProperties查看,將配置文件中對應的值和HttpProperties綁定起來; //并把HttpProperties加入到ioc容器中 @EnableConfigurationProperties(HttpProperties.class)//Spring底層@Conditional注解 //根據不同的條件判斷,如果滿足指定的條件,整個配置類里面的配置就會生效; //這里的意思就是判斷當前應用是否是web應用,如果是,當前配置類生效 @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)//判斷系統中有沒有CharacterEncodingFilter這個類,如果有配置類才生效 @ConditionalOnClass(CharacterEncodingFilter.class)//判斷配置文件中是否存在某個配置:spring.http.encoding.enabled; //matchIfMissing = true表明即使我們配置文件中不配置spring.http.encoding.enabled=true,該配置類也是默認生效的; @ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) public class HttpEncodingAutoConfiguration {//該類已經與配置文件綁定了private final HttpProperties.Encoding properties;//構建該自動配置類時將與配置文件綁定的配置類作為入參傳遞進去public HttpEncodingAutoConfiguration(HttpProperties properties) {this.properties = properties.getEncoding();}@Bean@ConditionalOnMissingBeanpublic CharacterEncodingFilter characterEncodingFilter() {CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();//注入bean時使用配置類中屬性的值進行初始化,相當于將配置文件中的值映射到了組件的某些屬性上filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));//注入配置好的beanreturn filter; } }

    一句話總結下自動配置類的工作過程 :

    • 首先容器會根據當前不同的條件判斷,決定這個配置類是否生效!
    • 一但這個配置類生效;這個配置類就會給容器中添加相應組件;
    • 這些組件的屬性是從對應的properties類中獲取的,這些類里面的每一個屬性又是和配置文件綁定的;
    • 所有在配置文件中能配置的屬性都是在xxxxProperties類中封裝著,配置文件可以配置什么內容,可以參照該前綴對應的屬性類中的屬性字段
    //從配置文件中獲取指定的值和bean的屬性進行綁定 @ConfigurationProperties(prefix = "spring.http") public class HttpProperties {// ..... }

    4.2 Spring Boot自動配置使用總結

    • SpringBoot啟動會加載大量的自動配置類

    • 我們首先可以看我們需要的功能有沒有在SpringBoot默認寫好的自動配置類當中;

    • 我們再來看這個自動配置類中到底配置了哪些組件;(只要我們要用的組件存在在其中,我們就不需要再手動配置了)

    • 給容器中自動配置類添加組件的時候,會從properties類中獲取某些屬性。我們只需要在配置文件中指定這些屬性的值即可;

      • xxxxAutoConfigurartion:自動配置類;給容器中添加組件
      • xxxxProperties:封裝配置文件中相關屬性;

    了解完自動裝配的原理后,我們來關注一個細節問題,自動配置類必須在一定的條件下才能生效;@Conditional派生注解(Spring注解版原生的@Conditional作用)

    作用:必須是@Conditional指定的條件成立,才給容器中添加組件,配置里面的所有內容才生效;

    序號@Conditional擴展注解作用(判斷是否滿足當前條件)
    1@ConditionalOnWebApplication當前項目是Web項目的條件下
    2@ConditionalOnNotWebApplication當前項目不是Web項目的條件下
    3@ConditionalOnResource類路徑下是否有指定的資源
    4@ConditionalOnExpression基于SpEL表達式作為判斷條件
    5@ConditionalOnMissingBean當容器中沒有指定Bean的情況下
    6@ConditionalOnBean當容器中有指定的Bean的條件下
    7@ConditionalOnSingleCandidate當指定的Bean在容器中只有一個,或者在有多個Bean的情況下,用來指定首選的Bean
    8@ConditionalOnJava基于JVM版本作為判斷條件
    9@ConditionalOnMissingClass當類路徑下沒有指定的類的條件下
    10@ConditionalOnClass當類路徑下有指定的類的條件下
    11@ConditionalOnProperty指定的屬性是否有指定的值

    那么多的自動配置類,必須在一定的條件下才能生效;也就是說,我們加載了這么多的配置類,但不是所有的都生效了。

    我們怎么知道哪些自動配置類生效?

    我們可以通過啟用 debug=true屬性;來讓控制臺打印自動配置報告,這樣我們就可以很方便的知道哪些自動配置類生效;

    #在配置文件中開啟springboot的調試類 debug=true

    Positive matches:(自動配置類啟用的:正匹配)

    Positive matches: -----------------AopAutoConfiguration matched:- @ConditionalOnClass found required classes 'org.springframework.context.annotation.EnableAspectJAutoProxy', 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice', 'org.aspectj.weaver.AnnotatedElement' (OnClassCondition)- @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)AopAutoConfiguration.CglibAutoProxyConfiguration matched:- @ConditionalOnProperty (spring.aop.proxy-target-class=true) matched (OnPropertyCondition)AuditAutoConfiguration#auditListener matched:- @ConditionalOnMissingBean (types: org.springframework.boot.actuate.audit.listener.AbstractAuditListener; SearchStrategy: all) did not find any beans (OnBeanCondition)AuditAutoConfiguration#authenticationAuditListener matched:- @ConditionalOnClass found required class 'org.springframework.security.authentication.event.AbstractAuthenticationEvent' (OnClassCondition)- @ConditionalOnMissingBean (types: org.springframework.boot.actuate.security.AbstractAuthenticationAuditListener; SearchStrategy: all) did not find any beans (OnBeanCondition)

    Negative matches:(沒有啟動,沒有匹配成功的自動配置類:負匹配)

    Negative matches: -----------------ActiveMQAutoConfiguration:Did not match:- @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)AopAutoConfiguration.JdkDynamicAutoProxyConfiguration:Did not match:- @ConditionalOnProperty (spring.aop.proxy-target-class=false) did not find property 'proxy-target-class' (OnPropertyCondition)AppOpticsMetricsExportAutoConfiguration:Did not match:- @ConditionalOnClass did not find required class 'io.micrometer.appoptics.AppOpticsMeterRegistry' (OnClassCondition)ArtemisAutoConfiguration:Did not match:- @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)

    Exclusions、Unconditional classes(排除的、沒有限定條件的自動配置類):

    Exclusions: -----------org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfigurationUnconditional classes: ----------------------org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfigurationorg.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfigurationorg.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfigurationorg.springframework.boot.actuate.autoconfigure.info.InfoContributorAutoConfiguration

    總結

    以上是生活随笔為你收集整理的企业级spring-boot案例-自定义Spring Boot Starter的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。