最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

手把手教你自定義自己SpringBoot Starter組件源碼剖析

2023-07-07 09:31 作者:程序員三時  | 我要投稿

我們知道SpringBoot Starter也就是啟動器。是SpringBoot組件化的一大優(yōu)點?;谶@個思想,基于這個思想SpringBoot 才變得非常強大,官方給我們提供很多開箱即用的啟動器。

Spring Boot Starter 是 Spring Boot 的一個重要特性,它有以下優(yōu)點:

  1. 「依賴管理」:Starter 自動處理項目的依賴關系,使得開發(fā)者無需手動添加和管理每個依賴。

  2. 「自動配置」:Starter 提供了一種自動配置的方式,可以根據(jù)你的 classpath 和你定義的屬性自動配置 Spring 應用。

  3. 「簡化開發(fā)」:通過提供各種服務的 Starter(如數(shù)據(jù)庫、安全、緩存等),極大地簡化了開發(fā)過程。

  4. 「減少樣板代碼」:由于 Starter 的自動配置和依賴管理,開發(fā)者可以專注于業(yè)務邏輯,而不是配置和基礎設施代碼。

  5. 「快速原型開發(fā)」:使用 Starter 可以快速創(chuàng)建可運行的原型。

  6. 「易于理解和使用」:Spring Boot Starter 的設計目標之一就是讓非專業(yè)的開發(fā)者也能快速上手。

  7. 「社區(qū)支持」:除了官方提供的 Starter,還有大量的社區(qū)提供的 Starter,可以滿足各種特定需求。

我現(xiàn)在手把手教大家如何封裝自己的「starter」 做自己的springboot組件,當然你也可以發(fā)布自己的「starter」 到maven中央倉庫供大家使用

剖析SpringBoot自帶Starter

我們以「WebMvcAutoConfiguration」這個自動加載為例

?

自動配置類要能加載,有一個要求,源碼分析結果是,需要在\META-INF\spring.factories中做如下配置

?

#?Auto?Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\

這樣SpringBoot在啟動完成時候,會找到我們引入,的「starter」 找到\META-INF\spring.factories 屬性文件,找到需要自動加載配置的類路徑,然后幫我們自動注入到「Spring IOC」 容器,我們在項目中就可以直接使用了。

這里實現(xiàn)自動加載還要依賴一些注解如:

@Configuration?//?指定這個類是個配置類
@ConditionalOnXXX?//?在指定條件成立的情況下自動配置類生效
@AutoConfigureOrder?//配置類順序
@AutoConfigureAfter?//?在哪個配置類之后
@Bean?//給容器中添加組件

@ConfigurationProperties?//結合相關的XXXProperties類?來綁定相關的配置
@EnableConfigurationProperties?//?讓XXXProperties加入到容器中,別人就可以自動裝配

自定義自己的starter

剖析了SpringBoot 官方的starter 我們自定義自己的starter,(我們仿照著寫)

命名規(guī)范

配置提示

如果自定義屬性文件中,需要IDEA智能提示需要引入

? ? ? <dependency> ? ? ? ? ? ?<groupId>org.springframework.boot</groupId> ? ? ? ? ? ?<artifactId>spring-boot-configuration-processor</artifactId> ? ? ? ? ? ?<optional>true</optional> ? ? ? ?</dependency>

定義starter

這里我以自己封裝總結我工作以來總結項目封裝的一個SpringBoot starter為例

?<dependency>
????????????<groupId>cn.soboys</groupId>
????????????<artifactId>rest-api-spring-boot-starter</artifactId>
????????????<version>1.2.0</version>
????????</dependency>

就是我自己封裝的start。已經(jīng)發(fā)布中央倉庫。

目前更新版本1.3.0 功能如下

  1. 支持一鍵配置自定義RestFull API 統(tǒng)一格式返回

  2. 支持RestFull API 錯誤國際化

  3. 支持全局異常處理,全局參數(shù)驗證處理

  4. 業(yè)務錯誤斷言工具封裝,遵循錯誤優(yōu)先返回原則

  5. redis工作封裝。支持所有key操作工具

  6. RestTemplate 封裝 POST,GET 請求工具

  7. 日志集成。自定義日志路徑,按照日志等級分類,支持壓縮和文件大小分割。按時間顯示

  8. 工具庫集成 集成了lombok,hutool,commons-lang3,guava。不需要自己單個引入

  9. 集成mybatisPlus一鍵代碼生成

rest-api-spring-boot-starter倉庫地址github

  1. 自定義配置屬性文件

rest-api:
??enabled:?false
??logging:
????path:?./logs
??i18n:
????#?若前端無header傳參則返回中文信息
????i18n-header:?Lang
????default-lang:?cn
????message:
??????#?admin
??????internal_server_error:
????????en:?Internal?Server?Error
????????cn:?系統(tǒng)錯誤
??????not_found:
????????en:?Not?Found
????????cn:?請求資源不存在

  1. 定義屬性配置類

package?cn.soboys.restapispringbootstarter.i18n;


import?lombok.Data;
import?org.springframework.boot.context.properties.ConfigurationProperties;
import?org.springframework.boot.context.properties.EnableConfigurationProperties;
import?org.springframework.context.annotation.Configuration;


import?java.util.Map;
import?java.util.Optional;

/**
?*?@author?公眾號?程序員三時
?*?@version?1.0
?*?@date?2023/6/26?11:55
?*?@webSite?https://github.com/coder-amiao
?*/

//@PropertySource(value?=?"classpath:i18n.yaml",?factory?=?YamlPropertySourceFactory.class)
@Configuration
@ConfigurationProperties(prefix?=?"rest-api.i18n")
@Data
public?class?I18NMessage?{
????/**
?????*?message-key:<lang:message>
?????*/

????private?Map<String,?Map<String,?String>>?message;
????/**
?????*?Default?language?setting?(Default?"cn").
?????*/

????private?String?defaultLang?=?"cn";


????private?String?i18nHeader?=?"Lang";


????/**
?????*?get?i18n?message
?????*
?????*?@param?key
?????*?@param?language
?????*?@return
?????*/

????public?String?message(I18NKey?key,?String?language)?{
????????return?Optional.ofNullable(message.get(key.key()))
????????????????.map(map?->?map.get(language?==?null???defaultLang?:?language))
????????????????.orElse(key.key());
????}

????/**
?????*?get?i18n?message
?????*
?????*?@param?key
?????*?@param?language
?????*?@return
?????*/

????public?String?message(String?key,?String?language)?{
????????return?Optional.ofNullable(message.get(key))
????????????????.map(map?->?map.get(language?==?null???defaultLang?:?language))
????????????????.orElse(key);
????}

}

  1. 定義BeanAutoConfiguration自動加載配置類

package?cn.soboys.restapispringbootstarter.config;

import?cn.soboys.restapispringbootstarter.ApplicationRunner;
import?cn.soboys.restapispringbootstarter.ExceptionHandler;
import?cn.soboys.restapispringbootstarter.ResultHandler;
import?cn.soboys.restapispringbootstarter.aop.LimitAspect;
import?cn.soboys.restapispringbootstarter.i18n.I18NMessage;
import?cn.soboys.restapispringbootstarter.utils.RedisTempUtil;
import?cn.soboys.restapispringbootstarter.utils.RestFulTemp;
import?org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import?org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import?org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import?org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import?org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import?org.springframework.context.annotation.Bean;
import?org.springframework.context.annotation.Configuration;
import?org.springframework.data.redis.core.RedisTemplate;
import?org.springframework.http.client.ClientHttpRequestFactory;
import?org.springframework.http.client.SimpleClientHttpRequestFactory;
import?org.springframework.http.converter.HttpMessageConverter;
import?org.springframework.http.converter.StringHttpMessageConverter;
import?org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import?org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import?org.springframework.web.client.RestTemplate;

import?java.nio.charset.Charset;
import?java.util.List;

/**
?*?@author?公眾號?程序員三時
?*?@version?1.0
?*?@date?2023/6/27?11:36
?*?@webSite?https://github.com/coder-amiao
?*/

@Configuration
@ConditionalOnProperty(name?=?"rest-api.enabled",?havingValue?=?"true")
public?class?BeanAutoConfiguration?{


????@Bean
????public?I18NMessage?i18NMessage()?{
????????return?new?I18NMessage();
????}

????@Bean
????public?ResultHandler?resultHandler()?{
????????return?new?ResultHandler();
????}

????@Bean
????public?ExceptionHandler?exceptionHandler()?{
????????return?new?ExceptionHandler();
????}

????@Bean
????public?StartupApplicationListener?startupApplicationListener()?{
????????return?new?StartupApplicationListener();
????}


????@Bean
????public?RestApiProperties?restApiProperties()?{
????????return?new?RestApiProperties();
????}

????@Bean
????public?RestApiProperties.LoggingProperties?loggingProperties(RestApiProperties?restApiProperties)?{
????????return?restApiProperties.new?LoggingProperties();
????}

????@Bean
????public?ApplicationRunner?applicationRunner()?{
????????return?new?ApplicationRunner();
????}




????/**
?????*?restTemplate?自動注入
?????*/

????@Configuration
????@ConditionalOnProperty(name?=?"rest-api.enabled",?havingValue?=?"true")
????class?RestTemplateConfig?{
????????/**
?????????*?第三方請求要求的默認編碼
?????????*/

????????private?final?Charset?thirdRequest?=?Charset.forName("utf-8");

????????@Bean
????????public?RestTemplate?restTemplate(ClientHttpRequestFactory?factory)?{
????????????RestTemplate?restTemplate?=?new?RestTemplate(factory);
????????????//?處理請求中文亂碼問題
????????????List<HttpMessageConverter<?>>?messageConverters?=?restTemplate.getMessageConverters();
????????????for?(HttpMessageConverter<?>?messageConverter?:?messageConverters)?{
????????????????if?(messageConverter?instanceof?StringHttpMessageConverter)?{
????????????????????((StringHttpMessageConverter)?messageConverter).setDefaultCharset(thirdRequest);
????????????????}
????????????????if?(messageConverter?instanceof?MappingJackson2HttpMessageConverter)?{
????????????????????((MappingJackson2HttpMessageConverter)?messageConverter).setDefaultCharset(thirdRequest);
????????????????}
????????????????if?(messageConverter?instanceof?AllEncompassingFormHttpMessageConverter)?{
????????????????????((AllEncompassingFormHttpMessageConverter)?messageConverter).setCharset(thirdRequest);
????????????????}
????????????}
????????????return?restTemplate;
????????}

????????@Bean
????????public?ClientHttpRequestFactory?simpleClientHttpRequestFactory()?{
????????????SimpleClientHttpRequestFactory?factory?=?new?SimpleClientHttpRequestFactory();
????????????factory.setConnectTimeout(15000);
????????????factory.setReadTimeout(5000);
????????????return?factory;
????????}


????????@Bean
????????public?RestFulTemp?restFulTemp()?{
????????????return?new?RestFulTemp();
????????}

????}

}

  1. 自動裝配 在項目

spring.factories 配置自己加載配置類

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.soboys.restapispringbootstarter.config.BeanAutoConfiguration,\
cn.soboys.restapispringbootstarter.config.BeanAutoConfiguration.RestTemplateConfig,\
cn.soboys.restapispringbootstarter.utils.RedisTempUtil\

?

擴展思考,我們可以看到SpringBoot官方stater 很多啟用都類似@Enablexxx注解 這個怎么實現(xiàn)。我的rest-api-spring-boot-starter 1.3.0已經(jīng)實現(xiàn)不需要在「application.properties」配置一行 直接在啟動類或者配置類使用EnableRestFullApi就可以使用全部功能

?

完善文檔使用可以看我

SpringBoot定義優(yōu)雅全局統(tǒng)一Restful API 響應框架完結撒花篇封裝starter組件

這篇文章

到此自己定義「starter」就寫完了 接下來就是打包,發(fā)布到「maven中央倉庫」

我會在 下一篇文章繼續(xù)分享

留下你的思考,「關注公眾 程序員三時」

持續(xù)輸出優(yōu)質(zhì)內(nèi)容 希望給你帶來一點啟發(fā)和幫助


手把手教你自定義自己SpringBoot Starter組件源碼剖析的評論 (共 條)

分享到微博請遵守國家法律
安顺市| 乌海市| 宁化县| 体育| 元江| 汤原县| 炉霍县| 平度市| 马龙县| 汪清县| 手游| 泸西县| 宝丰县| 溧阳市| 乐至县| 平利县| 伊吾县| 盐城市| 山东| 荥阳市| 谷城县| 潞城市| 靖江市| 曲靖市| 横山县| 仙桃市| 永济市| 罗甸县| 雷波县| 界首市| 砚山县| 怀安县| 隆林| 防城港市| 鄂托克前旗| 通化市| 迁安市| 长岛县| 华阴市| 雅江县| 家居|