最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

KotlinScript構(gòu)建SpringBootStarter保姆級教程

 更新時(shí)間:2022年09月26日 14:40:16   作者:looko  
這篇文章主要為大家介紹了KotlinScript構(gòu)建SpringBootStarter的保姆級教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

因業(yè)務(wù)需要, 公司內(nèi)需要使用 SpringBoot Starter 構(gòu)建 SDK. 不同的是使用了更為靈活的 Kotlin 語言, 構(gòu)建腳本也換成了 Kotlin Script.

  • 框架: SpringBoot
  • 業(yè)務(wù)代碼語言: Kotlin
  • 構(gòu)建工具: Gradle
  • 構(gòu)建腳本: Kotlin Script (不同于 Groovy, 是 Kotlin 自家的 DSL, 文件后綴為 .kts)
  • 開發(fā)工具: Idea CE

本文主要分幾個(gè)步驟:

  • 用 Kotlin 寫一個(gè)簡單 SpringBoot Starter
  • 進(jìn)階一: 復(fù)雜配置參數(shù)的寫法
  • 進(jìn)階二: starter 單元測試
  • 使用 Kotlin Script 構(gòu)建成 Maven 依賴
  • 集成測試

不會(huì)太詳細(xì), 但會(huì)把主要的內(nèi)容和要注意的點(diǎn)記錄下來.

一 如何用 Kotlin 寫一個(gè)簡單 SpringBoot Starter

1 分析

SpringBoot Starter 實(shí)現(xiàn)的原理網(wǎng)絡(luò)上已經(jīng)有很多, 就不細(xì)說了, 我總結(jié)了一下核心的運(yùn)作邏輯, 就是下面我畫的這張圖:

所以要寫一個(gè) starter, 無論用什么語言本質(zhì)上都是一樣的.

以下步驟可能與部分網(wǎng)絡(luò)教程不太一樣, 主要是根據(jù)上面的圖方向來分析說明的, 是一個(gè)按照邏輯需求來定義的順序:

  • resources 下新建 META-INF 文件夾, 寫個(gè) spring.factories 文件 (文件內(nèi)容見后文), 用于指定一個(gè)配置類.
  • 寫配置類, 主要職能是業(yè)務(wù) Bean 與 其相關(guān)配置的樞紐, 它將對業(yè)務(wù) Bean 進(jìn)行配置, 配置的內(nèi)容來源于后面我們自己定義的配置文件寫法.
  • 寫業(yè)務(wù) Bean, 也就是想讓別人引用這個(gè) starter 依賴后可以使用的類.
  • 寫配置屬性聲明類, 是個(gè) POJO 類, 聲明了可以在 application.properties 或者 application.yml 里能使用的配置屬性
  • 可選, 寫一個(gè) json 文件用于給使用者寫 application.properties 的時(shí)候提示一些信息

實(shí)際寫代碼時(shí)順序按需即可.

2 簡單案例設(shè)計(jì)

比如, 我想實(shí)現(xiàn)一個(gè)郵件告警的 SDK.

這個(gè) SDK 有一個(gè)類 AlarmByEmails, 集成此 SDK 的項(xiàng)目通過如下的 application.properties 配置后, 可通過 AlarmByEmails 的某個(gè)方法調(diào)用 xxx@163.com 發(fā)送郵件給 yyy@163.com.

(考慮到后續(xù) starter 測試用 yml 方式有所不便, 所以 starter 中測試使用 properties 文件)

simple.alarm.email.host=smtp.163.com # 郵件協(xié)議服務(wù)器
simple.alarm.email.senderEmail=xxx@163.com	# 發(fā)送方郵箱
simple.alarm.email.senderPassword=xxx	# 發(fā)送方郵箱的授權(quán)碼, 非密碼
simple.alarm.email.receiverEmail=yyy@163.com	# 接收方郵箱

怎么實(shí)現(xiàn)呢?

3 代碼實(shí)現(xiàn)

看個(gè)總體目錄結(jié)構(gòu)(已刪減無關(guān)文件):

├── build.gradle.kts
├── settings.gradle.kts
└── src
    └── main
        ├── kotlin
        │   └── com
        │       └── looko
        │           └── simplealarmspringbootstarter
        │               ├── autoconfigure
        │               │   ├── SimpleAlarmAutoConfiguration.kt
        │               │   └── properties
        │               │       └── EmailProperties.kt
        │               └── component
        │                   └── AlarmByEmails.kt
        └── resources
            ├── META-INF
            │   └── spring.factories
            └── test.properties

依賴項(xiàng)

基于 Kotlin 和 Gradle 新建 Spring Boot 項(xiàng)目, 名稱最好按照 Starter 創(chuàng)建的約定俗成規(guī)范 xxx-spring-boot-starter , 刪除啟動(dòng)類, 然后在 build.gradle.kts 的依賴中添加:

annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")

配置屬性聲明類: xxxProperties

這里的屬性就定義了配置文件的寫法.

@ConfigurationProperties(prefix = "simple.alarm.email")
data class EmailProperties(
  var host? = null,
  var senderEmail? = null,
  var senderPassword? = null,
  var receiverEmail? = null
)

注意:

  • 配置文件到 POJO 的屬性裝配是要用到 setter 的, 所以要定義為 var, 如果定義為 val , starter 被引用后, 程序啟動(dòng)階段在讀取相應(yīng)配置時(shí), 如果文件配置與默認(rèn)配置不一樣的話會(huì)報(bào)錯(cuò).
  • Spring 在處理這個(gè)類的時(shí)候會(huì)自動(dòng)屬性注入, 如果不寫缺省值的話啟動(dòng)找不到注入值會(huì)報(bào)錯(cuò).

業(yè)務(wù) Bean

屬性聲明好了, 該到用的時(shí)候了.

class AlarmByEmail(
  private val host,
  private val senderEmail,
  private val senderPassword,
  private val receiverEmail
) {
  fun sendMessage(content: String): Boolean {
    // 發(fā)郵件的實(shí)現(xiàn)
  }
}

此處使用了構(gòu)造器注入的方式, 也可以使用 setter 方式.

配置類: xxxAutoConfiguration

這是關(guān)鍵, 上面配置上的屬性和業(yè)務(wù) Bean 都有了, 如何把它倆關(guān)聯(lián)起來并注冊成 Spring Bean 呢?

@Configuration
@ConditionalOnClass(SimpleAlarmAutoConfiguration::class)
@EnableConfigurationProperties(value = [EmailProperties::class])
class SimpleAlarmAutoConfiguration {
    @Bean
    fun alarmByEmail(properties: EmailProperties): AlarmByEmail {
        return AlarmByEmail(
          properties.host,
          properties.senderEmail,
          properties.senderPassword,
          properties.receiverEmail
        )
    }
}

就是如此簡單.

@Configuration + @Bean 老組合了, 將一個(gè)類注冊為 Spring Bean.

@ConditionalOnClass, 是基于 @Conditional 的條件注解, 是 Spring4 提供的一種注解, 它的作用是按照設(shè)定的條件進(jìn)行判斷, 把滿足判斷條件的 Bean 注冊到 Spring 容器. 相關(guān)注解如下:

條件注解作用
@ConditionalOnBean當(dāng)上下文存在某個(gè)對象時(shí)才會(huì)實(shí)例化 Bean
@ConditionalOnClass某個(gè) Class 位于 classpath 路徑上才會(huì)實(shí)例化 Bean
@ConditionalOnExpression當(dāng) SpEL 表達(dá)式值為 true 的時(shí)候才會(huì)實(shí)例化 Bean
@ConditionalOnMissingBean當(dāng)上下文不存在某個(gè)對象時(shí)才會(huì)實(shí)例化 Bean
@ConditionalOnMissingClass某個(gè) Class 不在 classpath 路徑上才會(huì)實(shí)例化 Bean
@ConditionalOnNotWebApplication非 web 應(yīng)用才會(huì)實(shí)例化 Bean
@ConditionalOnWebApplicationweb 應(yīng)用才會(huì)實(shí)例化 Bean
@ConditionalOnProperty當(dāng)指定的屬性有指定的值時(shí)才會(huì)實(shí)例化 Bean
@ConditionalOnJava當(dāng) JVM 版本為指定的版本范圍時(shí)才會(huì)實(shí)例化 Bean
@ConditionalOnResource當(dāng) classpath 路徑下有指定的資源時(shí)才會(huì)實(shí)例化 Bean
@ConditionalOnJndi在 JNDI 存在時(shí)才會(huì)實(shí)例化 Bean
@ConditionalOnSingleCandidate當(dāng)指定的 Bean 在容器中只有一個(gè), 或者有多個(gè)但是指定了首選的 Bean 時(shí), 才會(huì)實(shí)例化 Bean

@EnableConfigurationProperties , 用于獲取配置聲明類, 原理不贅述.

spring.factories 文件

這個(gè)文件是上面寫好的自動(dòng)配置的入口, 有了它 Spring 才能讀到上面寫好的內(nèi)容:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.looko.simplealarmspringbootstarter.autoconfigure.SimpleAlarmAutoConfiguration

json 配置注釋文件

可不寫, 用來作為寫屬性時(shí)的提示.

spring-configuration-metadata.json :

{
  "properties": [
    {
      "name": "simple.alarm.email.host",
      "type": "java.lang.String",
      "description": "郵件服務(wù)器地址."
    },
    {
      "name": "simple.alarm.email.senderEmail",
      "type": "java.lang.String",
      "description": "發(fā)送者郵箱."
    },
    {
      "name": "simple.alarm.email.senderPassword",
      "type": "java.lang.String",
      "description": "發(fā)送者授權(quán)碼."
    },
    {
      "name": "simple.alarm.email.receiverEmail",
      "type": "java.lang.String",
      "description": "接收者郵箱."
    },
  ]
}

二 進(jìn)階: 復(fù)雜配置參數(shù)的寫法

如果我想通過配置配多個(gè)發(fā)送者的郵箱, 每個(gè)郵箱又可以配置, 該如何實(shí)現(xiàn)呢?

比如, 使用 xxx@163.com 發(fā)送郵件給 yyy@163.com, 而使用 yyy@163.com 則可以同時(shí)發(fā)郵件給 zzz@163.com 和 xxx@163.com.

配置的寫法:

simple.alarm.email.configs[0].host=smtp.163.com
simple.alarm.email.configs[0].senderEmail=xxx@163.com
simple.alarm.email.configs[0].senderPassword=xxx
simple.alarm.email.configs[0].receivers[0]=yyy@163.com
simple.alarm.email.configs[1].host=smtp.163.com
simple.alarm.email.configs[1].senderEmail=yyy@163.com
simple.alarm.email.configs[1].senderPassword=yyy
simple.alarm.email.configs[1].receivers[0]=zzz@163.com
simple.alarm.email.configs[1].receivers[0]=xxx@163.com

將郵箱按發(fā)送者分成了一個(gè)個(gè)的 configs 數(shù)組, 每個(gè) configs 下面保存了發(fā)送的配置, 同時(shí)接收者也配置成了數(shù)組,

這樣就完美符合需求了.

那么 properties 等類怎么寫呢?

EmailProperties:

@ConfigurationProperties(prefix = "simple.alarm.email")
data class EmailProperties(
    var configs: Array<EmailConfigEntity> = arrayOf()
)

這是抽出來的 EmailConfigEntity, 注意用 var:

data class EmailConfigEntity(
    var host: String? = null,
    var senderEmail: String? = null,
    var senderPassword: String? = null,
    var receivers: Array<String> = arrayOf()
)

因?yàn)閰?shù)抽出來了, 所以 AlarmByEmail 的入?yún)⒁惨鄳?yīng)調(diào)整:

class AlarmByEmail(
  private val configs: Array<EmailConfigEntity>
) {
  fun sendMessage(content: String): Boolean {
    // 發(fā)郵件的實(shí)現(xiàn)
  }
}

SimpleAlarmAutoConfiguration 相應(yīng)調(diào)整:

@Configuration
@ConditionalOnClass(SimpleAlarmAutoConfiguration::class)
@EnableConfigurationProperties(value = [EmailProperties::class])
class SimpleAlarmAutoConfiguration {
    @Bean
    fun alarmByEmail(properties: EmailProperties): AlarmByEmail {
        return AlarmByEmail(
          properties.configs
        )
    }
}

這樣就全部完成了.

三 進(jìn)階: Starter 單元測試

測試是必要的.

單獨(dú)的 Spring-boot-starter 并不是一個(gè)完整的應(yīng)用 大多數(shù)時(shí)候都是作為一個(gè)實(shí)際應(yīng)用的一部分存在 如果是通過另一個(gè)項(xiàng)目引用并啟動(dòng)項(xiàng)目的話, 會(huì)在 Debug 時(shí)造成不必要的麻煩 所以需要?jiǎng)?chuàng)建能夠獨(dú)立運(yùn)行的 Test

依賴

testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.boot:spring-boot-test-autoconfigure")

配置文件

resourses 路徑下的 test.properties:

simple.alarm.email.configs[0].host=smtp.163.com
simple.alarm.email.configs[0].senderEmail=xxx@163.com
simple.alarm.email.configs[0].senderPassword=xxx
simple.alarm.email.configs[0].receivers[0]=yyy@163.com
simple.alarm.email.configs[1].host=smtp.163.com
simple.alarm.email.configs[1].senderEmail=yyy@163.com
simple.alarm.email.configs[1].senderPassword=yyy
simple.alarm.email.configs[1].receivers[0]=zzz@163.com
simple.alarm.email.configs[1].receivers[0]=xxx@163.com

測試類

如下, 通過注解指定自動(dòng)配置類和配置文件

@SpringBootTest(classes = [SimpleAlarmAutoConfiguration::class])
@TestPropertySource("classpath:test.properties")
class SimpleAlarmSpringBootStarterApplicationTests {
    @Test
    fun contextLoads() {
    }
    @Autowired
    lateinit var alarmByEmail: AlarmByEmail
    @Test
    fun testAlarmByEmail() {
        assert(alarmByEmail.sendMessage("Message Content"))
    }
}

四 如何使用 Kotlin Script 構(gòu)建成 Maven 依賴

使用 maven-publish 插件.

build.gradle.kts 中, 主要用法如下 :

// ...
plugins {
    // ...
    `maven-publish`
}
// ...
val sourcesJar by tasks.registering(Jar::class) {
    archiveClassifier.set("sources")
    from(sourceSets.main.get().allSource)
}
publishing {
    publications {
        register("alarm", MavenPublication::class) {
            groupId = "com.looko"
            artifactId = "simple-alarm-spring-boot-starter"
            version = "0.0.1-SNAPSHOT"
            from(components["java"])
            artifact(sourcesJar.get())
        }
    }
    repositories {
        maven {
            mavenLocal()
        }
    }
}
// ...

在 IDEA 界面 double-ctrl 呼出 run 窗口, 找到 gradle publishToMavenLocal 回車就能打包到 .m2 目錄下了.

或者在右側(cè) gradle 窗口中也能找到相應(yīng)的 gradle task.

如果打到倉庫的包里含有 plain 后綴, 不被 maven 識別的話, 可以在 build.gradle.kts 中添加如下配置解決:

tasks.getByName<Jar>("jar") {
	archiveClassifier.set("")
}

五 集成測試

依賴

testImplementation("com.looko:simple-alarm-spring-boot-starter:0.0.1-SNAPSHOT")

配置文件

application.properties

simple.alarm.email.configs[0].host=smtp.163.com
simple.alarm.email.configs[0].senderEmail=xxx@163.com
simple.alarm.email.configs[0].senderPassword=xxx
simple.alarm.email.configs[0].receivers[0]=yyy@163.com
simple.alarm.email.configs[1].host=smtp.163.com
simple.alarm.email.configs[1].senderEmail=yyy@163.com
simple.alarm.email.configs[1].senderPassword=yyy
simple.alarm.email.configs[1].receivers[0]=zzz@163.com
simple.alarm.email.configs[1].receivers[0]=xxx@163.com

或者 application.yml

simple:
  alarm:
    email:
      configs:
        - host: smtp.163.com
            senderEmail: xxx@163.com
            senderPassword: xxx
            receivers:
              - yyy@163.com
        - host: smtp.163.com
            senderEmail: yyy@163.com
            senderPassword: yyy
            receivers:
              - zzz@163.com
              - xxx@163.com

代碼

根據(jù)實(shí)際業(yè)務(wù)集成, 具體代碼略.

示例代碼:

gayhub 倉庫

以上就是KotlinScript 構(gòu)建 SpringBootStarter保姆級教程的詳細(xì)內(nèi)容,更多關(guān)于KotlinScript 構(gòu)建 SpringBootStarter的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JAVA線上常見問題排查手段匯總

    JAVA線上常見問題排查手段匯總

    這篇文章主要介紹了JAVA線上常見問題排查手段匯總,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • springmvc HttpServletRequest 如何獲取c:forEach的值

    springmvc HttpServletRequest 如何獲取c:forEach的值

    這篇文章主要介紹了springmvc HttpServletRequest 如何獲取c:forEach的值方法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java遞歸實(shí)現(xiàn)字符串全排列與全組合

    Java遞歸實(shí)現(xiàn)字符串全排列與全組合

    這篇文章主要為大家詳細(xì)介紹了Java遞歸實(shí)現(xiàn)字符串全排列與全組合,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • JAVA WEB中Servlet和Servlet容器的區(qū)別

    JAVA WEB中Servlet和Servlet容器的區(qū)別

    這篇文章主要介紹了JAVA WEB中Servlet和Servlet容器的區(qū)別,文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • Java中文件寫入內(nèi)容的幾種常見方法

    Java中文件寫入內(nèi)容的幾種常見方法

    本文主要介紹了Java中文件寫入內(nèi)容的幾種常見方法,主要包括使用NIO的Files工具類、通過commons-io的FileUtils工具類、RandomAccessFile、PrintWriter和BufferedWriter這幾種,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • springcloud gateway如何配置動(dòng)態(tài)路由

    springcloud gateway如何配置動(dòng)態(tài)路由

    本文主要介紹了在SpringCloudGateway中配置動(dòng)態(tài)路由的步驟,包括引入依賴、配置路由源、添加配置中心依賴、配置配置中心、定義路由規(guī)則和刷新配置等內(nèi)容,使路由規(guī)則在配置中心更新時(shí),無需重啟網(wǎng)關(guān)服務(wù)即可動(dòng)態(tài)應(yīng)用新的路由規(guī)則
    2024-10-10
  • mybatis調(diào)用mysql存儲(chǔ)過程(返回參數(shù),單結(jié)果集,多結(jié)果集)

    mybatis調(diào)用mysql存儲(chǔ)過程(返回參數(shù),單結(jié)果集,多結(jié)果集)

    本文主要介紹了mybatis調(diào)用mysql存儲(chǔ)過程(返回參數(shù),單結(jié)果集,多結(jié)果集),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • jenkins如何部署應(yīng)用到多個(gè)環(huán)境

    jenkins如何部署應(yīng)用到多個(gè)環(huán)境

    本文介紹了如何基于流水線的方式將應(yīng)用程序部署到多個(gè)環(huán)境,包括測試環(huán)境和生產(chǎn)環(huán)境,通過創(chuàng)建項(xiàng)目、設(shè)置參數(shù)、配置流水線、設(shè)置環(huán)境變量、配置Maven工具、構(gòu)建階段、部署測試環(huán)境和生產(chǎn)環(huán)境、以及清理階段,實(shí)現(xiàn)了自動(dòng)化部署流程
    2024-11-11
  • MyBatis中獲取Mysql數(shù)據(jù)庫插入記錄的主鍵值的實(shí)現(xiàn)

    MyBatis中獲取Mysql數(shù)據(jù)庫插入記錄的主鍵值的實(shí)現(xiàn)

    本文主要介紹了MyBatis中獲取Mysql數(shù)據(jù)庫插入記錄的主鍵值的實(shí)現(xiàn),包含了三種實(shí)現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • Java List的sort()方法改寫compare()實(shí)現(xiàn)升序,降序,倒序的案例

    Java List的sort()方法改寫compare()實(shí)現(xiàn)升序,降序,倒序的案例

    這篇文章主要介紹了Java List的sort()方法改寫compare()實(shí)現(xiàn)升序,降序,倒序的案例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03

最新評論

谷城县| 五大连池市| 洪江市| 吴桥县| 涪陵区| 海城市| 思南县| 缙云县| 青冈县| 正蓝旗| 洪湖市| 子长县| 小金县| 秦皇岛市| 青冈县| 新津县| 兴国县| 泾阳县| 凤台县| 翁源县| 富裕县| 谷城县| 镇雄县| 昂仁县| 绩溪县| 军事| 隆昌县| 洪洞县| 益阳市| 武鸣县| 石门县| 遂宁市| 都昌县| 芦溪县| 铜陵市| 五大连池市| 建阳市| 绍兴市| 科技| 高雄市| 石家庄市|