摘要:代碼如下所示自定義業(yè)務(wù)實現(xiàn)恒宇少年碼云消息內(nèi)容是否顯示消息內(nèi)容,我們內(nèi)的代碼比較簡單,根據(jù)屬性參數(shù)進(jìn)行返回格式化后的字符串。
在我們學(xué)習(xí)SpringBoot時都已經(jīng)了解到starter是SpringBoot的核心組成部分,SpringBoot為我們提供了盡可能完善的封裝,提供了一系列的自動化配置的starter插件,我們在使用spring-boot-starter-web時只需要在pom.xml配置文件內(nèi)添加依賴就可以了,我們之前傳統(tǒng)方式則是需要添加很多相關(guān)SpringMVC配置文件。而spring-boot-starter-web為我們提供了幾乎所有的默認(rèn)配置,很好的降低了使用框架時的復(fù)雜度。
因此在使用xx.starter時你就不用考慮該怎么配置,即便是有一些必要的配置在application.properties配置文件內(nèi)對應(yīng)配置就可以了,那好,為什么我在application.properties配置對應(yīng)屬性后xx.starter就可以獲取到并作出處理呢?下面我們帶著這個疑問來編寫我們自定義的starter讓我們深入了解SpringBoot
自定義starter并且通過spring-boot-autoconfigure完成自動化配置。
構(gòu)建項目創(chuàng)建starter項目我們并不需要創(chuàng)建SpringBoot項目,我們創(chuàng)建一個Maven項目就可以滿足我們的需求,創(chuàng)建項目完成后pom.xml配置信息如下所示:
4.0.0 com.yuqiyu chapter28 1.0.0 jar UTF-8 org.springframework.boot spring-boot-autoconfigure 1.5.4.RELEASE
我們這個starter并不做其他復(fù)雜邏輯的編寫,所以這里的依賴只是添加了spring-boot-autoconfigure,實戰(zhàn)開發(fā)時可以添加任意依賴到項目中。
配置映射參數(shù)實體我們在文章開頭埋下了一個疑問,starter是如何讀取application.properties或者application.yml配置文件內(nèi)需要的配置參數(shù)的呢?那么接下來我們就看看如何可以獲取自定義的配置信息。
SpringBoot在處理這種事情上早就已經(jīng)考慮到了,所以提供了一個注解@ConfigurationProperties,該注解可以完成將application.properties配置文件內(nèi)的有規(guī)則的配置參數(shù)映射到實體內(nèi)的field內(nèi),不過需要提供setter方法,自定義配置參數(shù)實體代碼如下所示:
package com.yuqiyu.chapter28; import org.springframework.boot.context.properties.ConfigurationProperties; /** * 配置文件實體映射 * ======================== * Created with IntelliJ IDEA. * User:恒宇少年 * Date:2017/7/22 * Time:22:51 * 碼云:http://git.oschina.net/jnyqy * ======================== */ @ConfigurationProperties(prefix = "hello") public class HelloProperties { //消息內(nèi)容 private String msg = "HengYu"; //是否顯示消息內(nèi)容 private boolean show = true; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public boolean isShow() { return show; } public void setShow(boolean show) { this.show = show; } }
在上面代碼中,@ConfigurationProperties注解內(nèi)我們使用到了屬性preffix,該屬性配置了讀取參數(shù)的前綴,根據(jù)上面的實體屬性對應(yīng)配置文件內(nèi)的配置則是hello.msg、hello.show,當(dāng)然我們提供了默認(rèn)值,配置文件內(nèi)不進(jìn)行配置時則是使用默認(rèn)值。
編寫自定義業(yè)務(wù)我們?yōu)樽远xstarter提供一個Service,并且提供一個名為sayHello的方法用于返回我們配置的msg內(nèi)容。代碼如下所示:
package com.yuqiyu.chapter28; /** * 自定義業(yè)務(wù)實現(xiàn) * ======================== * Created with IntelliJ IDEA. * User:恒宇少年 * Date:2017/7/22 * Time:22:54 * 碼云:http://git.oschina.net/jnyqy * ======================== */ public class HelloService { //消息內(nèi)容 private String msg; //是否顯示消息內(nèi)容 private boolean show = true; public String sayHello() { return show ? "Hello," + msg : "Hidden"; } public void setMsg(String msg) { this.msg = msg; } public void setShow(boolean show) { this.show = show; } }
我們Service內(nèi)的代碼比較簡單,根據(jù)屬性參數(shù)進(jìn)行返回格式化后的字符串。
接下來我們開始編寫自動配置,這一塊是starter的核心部分,配置該部分后在啟動項目時才會自動加載配置,當(dāng)然其中有很多細(xì)節(jié)性質(zhì)的配置
實現(xiàn)自動化配置自動化配置其實只是提供實體bean的驗證以及初始化,我們先來看看代碼:
package com.yuqiyu.chapter28; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * 自定義starter自動化配置 * ======================== * Created with IntelliJ IDEA. * User:恒宇少年 * Date:2017/7/22 * Time:22:56 * 碼云:http://git.oschina.net/jnyqy * ======================== */ @Configuration//開啟配置 @EnableConfigurationProperties(HelloProperties.class)//開啟使用映射實體對象 @ConditionalOnClass(HelloService.class)//存在HelloService時初始化該配置類 @ConditionalOnProperty//存在對應(yīng)配置信息時初始化該配置類 ( prefix = "hello",//存在配置前綴hello value = "enabled",//開啟 matchIfMissing = true//缺失檢查 ) public class HelloAutoConfiguration { //application.properties配置文件映射前綴實體對象 @Autowired private HelloProperties helloProperties; /** * 根據(jù)條件判斷不存在HelloService時初始化新bean到SpringIoc * @return */ @Bean//創(chuàng)建HelloService實體bean @ConditionalOnMissingBean(HelloService.class)//缺失HelloService實體bean時,初始化HelloService并添加到SpringIoc public HelloService helloService() { System.out.println(">>>The HelloService Not Found,Execute Create New Bean."); HelloService helloService = new HelloService(); helloService.setMsg(helloProperties.getMsg());//設(shè)置消息內(nèi)容 helloService.setShow(helloProperties.isShow());//設(shè)置是否顯示 return helloService; } }
自動化配置代碼中有很多我們之前沒有用到的注解配置,我們從上開始講解
@Configuration:這個配置就不用多做解釋了,我們一直在使用
@EnableConfigurationProperties:這是一個開啟使用配置參數(shù)的注解,value值就是我們配置實體參數(shù)映射的ClassType,將配置實體作為配置來源。
有關(guān)@ConditionalOnXxx相關(guān)的注解這里要系統(tǒng)的說下,因為這個是我們配置的關(guān)鍵,根據(jù)名稱我們可以理解為具有Xxx條件,當(dāng)然它實際的意義也是如此,條件注解是一個系列,下面我們詳細(xì)做出解釋
@ConditionalOnBean:當(dāng)SpringIoc容器內(nèi)存在指定Bean的條件
@ConditionalOnClass:當(dāng)SpringIoc容器內(nèi)存在指定Class的條件
@ConditionalOnExpression:基于SpEL表達(dá)式作為判斷條件
@ConditionalOnJava:基于JVM版本作為判斷條件
@ConditionalOnJndi:在JNDI存在時查找指定的位置
@ConditionalOnMissingBean:當(dāng)SpringIoc容器內(nèi)不存在指定Bean的條件
@ConditionalOnMissingClass:當(dāng)SpringIoc容器內(nèi)不存在指定Class的條件
@ConditionalOnNotWebApplication:當(dāng)前項目不是Web項目的條件
@ConditionalOnProperty:指定的屬性是否有指定的值
@ConditionalOnResource:類路徑是否有指定的值
@ConditionalOnSingleCandidate:當(dāng)指定Bean在SpringIoc容器內(nèi)只有一個,或者雖然有多個但是指定首選的Bean
@ConditionalOnWebApplication:當(dāng)前項目是Web項目的條件
以上注解都是元注解@Conditional演變而來的,根據(jù)不用的條件對應(yīng)創(chuàng)建以上的具體條件注解。
到目前為止我們還沒有完成自動化配置starter,我們需要了解SpringBoot運(yùn)作原理后才可以完成后續(xù)編碼。
Starter自動化運(yùn)作原理在注解@SpringBootApplication上存在一個開啟自動化配置的注解@EnableAutoConfiguration來完成自動化配置,注解源碼如下所示:
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.boot.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Import; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({EnableAutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class>[] exclude() default {}; String[] excludeName() default {}; }
在@EnableAutoConfiguration注解內(nèi)使用到了@import注解來完成導(dǎo)入配置的功能,而EnableAutoConfigurationImportSelector內(nèi)部則是使用了SpringFactoriesLoader.loadFactoryNames方法進(jìn)行掃描具有META-INF/spring.factories文件的jar包。我們可以先來看下spring-boot-autoconfigure包內(nèi)的spring.factories文件內(nèi)容,如下所示:
# Initializers org.springframework.context.ApplicationContextInitializer= org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer, org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer # Application Listeners org.springframework.context.ApplicationListener= org.springframework.boot.autoconfigure.BackgroundPreinitializer # Auto Configuration Import Listeners org.springframework.boot.autoconfigure.AutoConfigurationImportListener= org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener # Auto Configuration Import Filters org.springframework.boot.autoconfigure.AutoConfigurationImportFilter= org.springframework.boot.autoconfigure.condition.OnClassCondition # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration= org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration, org.springframework.boot.autoconfigure.aop.AopAutoConfiguration, .....省略
可以看到配置的結(jié)構(gòu)形式是Key=>Value形式,多個Value時使用,隔開,那我們在自定義starter內(nèi)也可以使用這種形式來完成,我們的目的是為了完成自動化配置,所以我們這里Key則是需要使用org.springframework.boot.autoconfigure.EnableAutoConfiguration
自定義spring.factories我們在src/main/resource目錄下創(chuàng)建META-INF目錄,并在目錄內(nèi)添加文件spring.factories,具體內(nèi)容如下所示:
#配置自定義Starter的自動化配置 org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.yuqiyu.chapter28.HelloAutoConfiguration
都目前為止我們的自定義starter已經(jīng)配置完成,下面我們需要新建一個SpringBoot項目來測試我們的自動化配置是否已經(jīng)生效。
創(chuàng)建測試SpringBoot項目在使用自定義starter之前需要將starter作Maven Jar Install到本地,我們使用idea工具自帶的maven命令完成該操作
步驟:工具右側(cè) -> Maven Projects -> Lifecycle -> install
創(chuàng)建測試項目的pom.xml配置文件內(nèi)容如下所示:
4.0.0 com.yuqiyu.sample test-spring-boot-starter-hello 0.0.1-SNAPSHOT jar test-spring-boot-starter-hello Demo project for Spring Boot org.springframework.boot spring-boot-starter-parent 1.5.4.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter com.yuqiyu chapter28 1.0.0 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin
我們只需要將依賴添加到pom.xml配置文件內(nèi)
運(yùn)行測試在運(yùn)行項目之前,我們打開application.properties配置文件開啟debug模式,查看自動化配置的輸出日志,配置內(nèi)容如下所示:
#顯示debug日志信息 debug=true
接下來我們啟動項目,在控制臺查找是否存在我們的HelloAutoConfiguration日志輸出,控制臺輸出內(nèi)容如下所示:
.....省略 >>>The HelloService Not Found,Execute Create New Bean. .....省略 HelloAutoConfiguration matched: - @ConditionalOnClass found required class "com.yuqiyu.chapter28.HelloService"; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition) - @ConditionalOnProperty (hello.enabled) matched (OnPropertyCondition) HelloAutoConfiguration#helloService matched: - @ConditionalOnMissingBean (types: com.yuqiyu.chapter28.HelloService; SearchStrategy: all) did not find any beans (OnBeanCondition) .....省略
在控制臺可以看到我們的自定義starter的自動化配置已經(jīng)生效了,并且根據(jù)@ConditionalOnMissingBean(HelloService.class)做出了條件注入HelloService實體bean到SpringIoc容器內(nèi)
編寫測試控制器我們來編寫一個簡單的測試控制器,查看HelloService在不配置參數(shù)情況下輸出格式化字符串內(nèi)容,控制器代碼如下所示:
package com.yuqiyu.sample.testspringbootstarterhello; import com.yuqiyu.chapter28.HelloService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * 測試自定義starter自動化配置HelloService * ======================== * Created with IntelliJ IDEA. * User:恒宇少年 * Date:2017/7/23 * Time:11:42 * 碼云:http://git.oschina.net/jnyqy * ======================== */ @RestController public class HelloController { //注入自定義starter內(nèi)邏輯 @Autowired HelloService helloService; /** * 測試訪問地址/hello * @return 格式化字符串 */ @RequestMapping(value = "/hello") public String sayHello() { return helloService.sayHello(); } }
接下來我們重啟下項目,訪問地址http://127.0.0.1:8080/hello,界面輸出內(nèi)容如下所示:
Hello,HengYu
界面輸出的內(nèi)容是我們默認(rèn)值,接下來我們在application.properties配置文件內(nèi)對應(yīng)添加hello.msg、hello.show配置參數(shù),如下所示:
#配置自定義starter參數(shù) hello.msg=HengYu Boy hello.show=true
重啟項目,再次訪問地址,界面輸出內(nèi)容如下所示:
Hello,HengYu Boy
我們的配置生效了,到目前為止我相信大家已經(jīng)明白了我們application.properties配置文件為什么可以作為統(tǒng)一配置入口,為什么配置后可以被對應(yīng)starter所使用。
總結(jié)以上內(nèi)容是本章的全部講解,本章主要講解了我們?nèi)绾巫远xstarter并且自動化配置到SpringBoot項目中,當(dāng)然里面還有很多神奇的地方需要大家去深入挖掘。
本章代碼已經(jīng)上傳到碼云:
網(wǎng)頁地址:http://git.oschina.net/jnyqy/lessons
Git地址:https://git.oschina.net/jnyqy/lessons.git
SpringBoot相關(guān)系列文章請訪問:目錄:SpringBoot學(xué)習(xí)目錄
QueryDSL相關(guān)系列文章請訪問:QueryDSL通用查詢框架學(xué)習(xí)目錄
感謝閱讀!
歡迎加入QQ技術(shù)交流群,共同進(jìn)步。
QQ技術(shù)交流群
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/67648.html
摘要:基于版本基于版本。由于中英行文差異,完全的逐字逐句翻譯會很冗余啰嗦。譯者在翻譯中同時參考了谷歌百度有道翻譯的譯文以及編程思想第四版中文版的部分內(nèi)容對其翻譯死板,生造名詞,語言精煉度差問題進(jìn)行規(guī)避和改正。 來源:LingCoder/OnJava8 主譯: LingCoder 參譯: LortSir 校對:nickChenyx E-mail: 本書原作者為 [美] Bru...
摘要:如何解決非集成情況下可能存在沖突的問題,有以下三種方案強(qiáng)制業(yè)務(wù)系統(tǒng)集成出現(xiàn)沖突時使用標(biāo)明其自己已存在的沖突,以防止按注入出現(xiàn)的沖突異常。 我們開發(fā)內(nèi)部用的二方庫時往往需要定義一些bean,這些bean中有的可能已經(jīng)被業(yè)務(wù)方系統(tǒng)配置使用了,在非SpringBoot方式集成中可能導(dǎo)致沖突。導(dǎo)致按type注入失敗(因為存在兩個已有的實現(xiàn))。為什么要強(qiáng)調(diào)非SpringBoot呢,因為Sprin...
摘要:還提供了全部參數(shù)的構(gòu)造函數(shù)的自動生成,該注解的作用域也是只有在實體類上,因為只有實體類才會存在構(gòu)造函數(shù)。當(dāng)然除了全部參數(shù)的構(gòu)造函數(shù),還提供了沒有參數(shù)的構(gòu)造函數(shù),使用方式與一致。 Lombok對于Java偷懶開發(fā)者來說應(yīng)該是比較中意的,恰恰筆者就是一個喜歡在小細(xì)節(jié)上偷懶來提高開發(fā)效率的人。所以在技術(shù)框架的海洋里尋找了很久才在GitHub開源平臺上找到,而在這之前國外很多程序猿一直使用該框...
摘要:創(chuàng)建工程涉及了,加上和的起步依賴。創(chuàng)建實體代碼清單如下創(chuàng)建頁面展示層啟動工程,訪問點(diǎn)擊參考資料源碼下載 這篇文件主要介紹通過springboot 去創(chuàng)建和提交一個表單。 創(chuàng)建工程 涉及了 web,加上spring-boot-starter-web和spring-boot-starter-thymeleaf的起步依賴。 org.springf...
閱讀 2686·2021-11-15 11:38
閱讀 2670·2021-11-04 16:13
閱讀 18402·2021-09-22 15:07
閱讀 1096·2019-08-30 15:55
閱讀 3323·2019-08-30 14:15
閱讀 1738·2019-08-29 13:59
閱讀 3285·2019-08-28 18:28
閱讀 1670·2019-08-23 18:29