<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring Boot Starter 萬字詳解!圖文并茂,還有誰不會?

          共 14113字,需瀏覽 29分鐘

           ·

          2022-01-01 16:35

          前沿技術(shù)早知道,彎道超車有希望

          積累超車資本,從關(guān)注DD開始

          一、Spring Boot的starter簡介

          1.1 什么是starter(場景啟動器)

          在SpringBoot出現(xiàn)之前,如果我們想使用SpringMVC來構(gòu)建我們的web項目,必須要做的幾件事情如下:

          • 首先項目中需要引入SpringMVC的依賴
          • 在web.xml中注冊SpringMVC的DispatcherServlet,并配置url映射
          • 編寫springmcv-servlet.xml,在其中配置SpringMVC中幾個重要的組件,處理映射器(HandlerMapping)、處理適配器(HandlerAdapter)、視圖解析器(ViewResolver)
          • applicationcontext.xml文件中引入springmvc-servlet.xml文件

          以上這幾步只是配置好了SpringMVC,如果我們還需要與數(shù)據(jù)庫進行交互,就要在application.xml中配置數(shù)據(jù)庫連接池DataSource,如果需要數(shù)據(jù)庫事務(wù),還需要配置TransactionManager…

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

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

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

          Spring Boot通過將我們常用的功能場景抽取出來,做成的一系列場景啟動器,這些啟動器幫我們導入了實現(xiàn)各個功能所需要依賴的全部組件,我們只需要在項目中引入這些starters,相關(guān)場景的所有依賴就會全部被導入進來,并且我們可以拋棄繁雜的配置,僅需要通過配置文件來進行少量的配置就可以使用相應的功能。

          二、Spring Boot場景啟動器的原理

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

          • 相關(guān)組件的自動導入
          • 相關(guān)組件的自動配置

          這兩件事情統(tǒng)一稱為SpringBoot的自動配置

          2.1 自動配置原理

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

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

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

          @SpringBootApplication注解內(nèi)部結(jié)構(gòu)如下圖所示:

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

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

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

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

          結(jié)論:

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

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

          首先我們先看下SpringBoot中配置文件與POJO類之間映射的方法,這是進行自動配置的基礎(chǔ)。來自阿里大佬的《LeetCode刷題答案》pdf新鮮出爐,年末面試必備!大家可以關(guān)注公眾號TJ君,回復LeetCode領(lǐng)取。

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

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

          自動配置類的工作流程:

          • 根據(jù)限定的條件向容器中注入組件
          • 使用xxxProperties對注入的組件的相關(guān)屬性進行配置
          //表示這是一個配置類,和以前編寫的配置文件一樣,也可以給容器中添加組件;
          @Configuration

          //將與配置文件綁定好的某個類注入到容器中,使其生效
          //進入這個HttpProperties查看,將配置文件中對應的值和HttpProperties綁定起來;
          //并把HttpProperties加入到ioc容器中
          @EnableConfigurationProperties(HttpProperties.class)

          //Spring底層@Conditional注解
          //根據(jù)不同的條件判斷,如果滿足指定的條件,整個配置類里面的配置就會生效;
          //這里的意思就是判斷當前應用是否是web應用,如果是,當前配置類生效
          @ConditionalOnWebApplication(type 
          = ConditionalOnWebApplication.Type.SERVLET)

          //判斷系統(tǒng)中有沒有CharacterEncodingFilter這個類,如果有配置類才生效
          @ConditionalOnClass(CharacterEncodingFilter.class)

          //判斷配置文件中是否存在某個配置:spring.http.encoding.enabled;
          //matchIfMissing 
          true表明即使我們配置文件中不配置pring.http.encoding.enabled=true,該配置類也是默認生效的;
          @ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
          public class HttpEncodingAutoConfiguration {

            //該類已經(jīng)與配置文件綁定了
           private final HttpProperties.Encoding properties;

            //構(gòu)建該自動配置類時將與配置文件綁定的配置類作為入?yún)鬟f進去
           public HttpEncodingAutoConfiguration(HttpProperties properties) {
            this.properties = properties.getEncoding();
           }

           @Bean
           @ConditionalOnMissingBean
           public CharacterEncodingFilter characterEncodingFilter() {
            CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
            filter.setEncoding(this.properties.getCharset().name()); //注入bean時使用配置類中屬性的值進行初始化,相當于將配置文件中的值映射到了組件的某些屬性上
            filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
            filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
            return filter; //注入配置好的bean
           }
          }

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

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

          2.2 Spring Boot自動配置使用總結(jié)

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

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

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

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


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

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

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

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

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

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

          #在配置文件中開啟springboot的調(diào)試類
          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.DataSourceAutoConfiguration


          Unconditional classes:
          ----------------------

              org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration

              org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration

              org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration

              org.springframework.boot.actuate.autoconfigure.info.InfoContributorAutoConfiguration

          三、自定義場景啟動器

          現(xiàn)在我們已經(jīng)了解了場景啟動器的概念以及其隱藏在背后的自動配置的原理,我們就可以自己來對SpringBoot進行功能拓展,定義我們自己的場景啟動器。如果您正在學習Spring Boot,那么推薦一個連載多年還在繼續(xù)更新的超級免費教程:http://blog.didispace.com/spring-boot-learning-2x/

          3.1 starter的命名規(guī)范

          官方命名空間

          • 前綴:spring-boot-starter-
          • 模式:spring-boot-starter-模塊名
          • 舉例:spring-boot-starter-web、spring-boot-starter-jdbc

          自定義命名空間

          • 后綴:-spring-boot-starter
          • 模式:模塊-spring-boot-starter
          • 舉例:mybatis-spring-boot-starter

          3.2 starter模塊整體結(jié)構(gòu)

          通過上邊的介紹,可以總結(jié)starter的整體實現(xiàn)邏輯主要由兩個基本部分組成:

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

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

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

          3.3 autoconfigure模塊開發(fā)

          3.3.1 依賴引入

          首先所有的自動配置模塊都要引入兩個jar包依賴:

          <dependencies>
               <dependency>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-autoconfigure</artifactId> 
                  <!-- 包含很多與自動配置相關(guān)的注解的定義,必須要引入 -->
               </dependency>
               <dependency>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-configuration-processor</artifactId> 
                 <!-- 非必須的,引入后可以在配置文件中輸入我們自定義配置的時候有相應的提示,也可以通過其他.properties文件為相關(guān)類進行屬性映射(SpringBoot默認使用application.yml)-->
                   <optional>true</optional>
               </dependency>
           <dependencies>

          其他依賴的選擇根據(jù)項目需要進行添加即可

          3.3.2 xxxAutoConfiguration的實現(xiàn)

          autoconfigure模塊中最重要的就是自動配置類的編寫,它為我們實現(xiàn)組件的自動配置與自動注入。

          在編寫自動配置類的時候,我們應該要考慮向容器中注入什么組件,如何去配置它。

          @Configuration 
          @ConditionalOnxxx
          @ConditionalOnxxx//限定自動配置類生效的一些條件
          @EnableConfigurationProperties(xxxProperties.class)
          public class xxxAutoConfiguration 
          {
           @Autowired
           private xxxProperties properties;
              @Bean
              public static BeanYouNeed beanYouNeed() {
               BeanYouNeed bean = new BeanYouNeed()
               bean.setField(properties.get(field));
               bean.setField(properties.get(field));
               bean.setField(properties.get(field));
                  ......
              }
          }
          3.3.3 xxxProperties的實現(xiàn)

          這是跟配置文件相綁定的類,里邊的屬性就是我們可以在配置文件中配置的內(nèi)容,然后通過@ConfigurationProperties將其與配置文件綁定:

          @ConfigurationProperties(prefix = "your properties"//使用@ConfigurationProperties注解綁定配置文件
          public class xxxProperties {

              private boolean enabled = true;

              private String clientId;

              private String beanName;

              private String scanBasePackage;

              private String path;

              private String token;
          }
          3.3.4 配置spring.factories文件

          在resource目錄下新建META-INF文件夾,在文件夾下新建spring.factories文件,并添加寫好的xxxAutoConfiguration類:

          org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
          com.meituan.xframe.boot.mcc.autoconfigure.xxxAutoConfiguration

          3.4 Starter模塊開發(fā)

          starter模塊中只進行依賴導入,在pom文件中添加對autoconfigure模塊的依賴,并添加一些其他必要的依賴項:

          <dependencies>
           ================================================================
           <!--添加了對autoconfigure模塊的引用-->
               <dependency>
                   <groupId>com.test.starter</groupId>
                   <artifactId>xxx-spring-boot-autoconfigure</artifactId>
               </dependency>
           ===============================================================
           <!--其他的一些必要依賴項-->
               <dependency>
                   <groupId>commons-collections</groupId>
                   <artifactId>commons-collections</artifactId>
               </dependency>
           </dependencies>

          這兩個模塊都開發(fā)完成之后,通過mvn install命令或者deploy命令將包發(fā)布到本地或者中央倉庫,即可直接在其他項目中引用我們自定義的starter模塊了

          來源:https://blog.csdn.net/qq_21310939/article/details/107401400

          作者:威尼斯的淚H| 圖文編輯:xj


          與優(yōu)秀的人在一起,自己也會優(yōu)秀起來

          高質(zhì)量技術(shù)交流群,您還沒加入嗎?

          趕緊點擊加入我們,享受一起成長的快樂!


          往期推薦

          一個讓我驚掉下巴的時間格式化問題!

          “VPN翻墻被大規(guī)模行政處罰” 是真的嗎?

          技術(shù)前沿:Redis推出性能碾壓ES和Mongo的大殺器

          墻裂推薦!卡神力作《代碼隨想錄》,上架首日賣爆!

          又雙叒有兄弟因為 YYYY-MM-dd 被叫去加班了...


          前沿技術(shù)早知道,彎道超車有希望

          積累超車資本,從關(guān)注DD開始


          點擊閱讀原文,送你免費Spring Boot教程!

          瀏覽 22
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  簧片大全免费观看视频了6666 | 国产青青草偷拍 | 亚洲无吗视频 | 九九九免费在线视频 | 操美女嫩逼网站 |