2020-02-29_自定義hello-spring-booter-starter

自定義hello-spring-booter-starter

1概述

1.1 SpringBoot核心原理

springboot的核心有如下四點:

① 起步依賴

核心是依賴傳遞,官方集成的第三方框架,從而實現(xiàn)版本管理

② 自動配置管理

通過springboot自動配置管理特性將其實例化到(自定義)類中程序啟動時,向Spring容器中導(dǎo)入很多配置,代替繁瑣的xml或注入Bean。注解中加入EnableConfigurationProperties,application.yml中的所有配置文件都會指向?qū)嶓w類。如server.port對應(yīng)的實體類ServerProperties(掃描包路徑為:org.springframework.boot.autoconfigure),

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)

public class ServerProperties {

③ 運行監(jiān)控管理Actuator

④ 命令行工具cli

可以使用SpringBoot快速的開發(fā)基于Spring框架的項目。由于圍繞SpringBoot存在很多開箱即用的Starter依賴,使得我們在開發(fā)業(yè)務(wù)代碼時能夠非常方便的、不需要過多關(guān)注框架的配置,而只需要關(guān)注業(yè)務(wù)即可。

1.2 常用的幾個注解說明

@Configuration:表明此類是一個配置類,將變?yōu)橐粋€bean被spring進(jìn)行管理。

@EnableConfigurationProperties:啟用屬性配置,將讀取HelloServiceProperties里面的屬性。

@ConditionalOnClass:當(dāng)類路徑下面有HelloServiceConfiguration此類時,自動配置。

@ConditionalOnProperty:判斷指定的屬性是否具備指定的值。

@ConditionalOnMissingBean:當(dāng)容器中沒有指定bean是,創(chuàng)建此bean。

@ConditionalOnBean:當(dāng)容器中有指定的Bean的條件下

@ConditionalOnClass:當(dāng)類路徑下有指定的類的條件下

@ConditionalOnExpression:基于SpEL表達(dá)式作為判斷條件

@ConditionalOnJava:基于JVM版本作為判斷條件

@ConditionalOnJndi:在JNDI存在的條件下查找指定的位置

@ConditionalOnMissingBean:當(dāng)容器中沒有指定Bean的情況下

@ConditionalOnMissingClass:當(dāng)類路徑下沒有指定的類的條件下

@ConditionalOnNotWebApplication:當(dāng)前項目不是Web項目的條件下

@ConditionalOnProperty:指定的屬性是否有指定的值

@ConditionalOnResource:類路徑下是否有指定的資源

@ConditionalOnSingleCandidate:當(dāng)指定的Bean在容器中只有一個,或者在有多個Bean的情況下,用來指定首選的Bean @ConditionalOnWebApplication:當(dāng)前項目是Web項目的條件下

1.3 @EnableAutoC vs @ImportAutoConfiguration

使用@EnableAutoConfiguration時會掃描整個類路徑下,包括依賴引入的jar包所有的自動配置類(被注解了@Configuration的類),嘗試進(jìn)行自動配置。比如,tomcat-embedded.jar。

而@ImportAutoConfiguration只運行在你注解中提供的配置類。

下面是一個Spring Boot入口方法中使用@ImportAutoConfiguration的列子:

@ComponentScan("path.to.your.controllers")

@ImportAutoConfiguration({

WebMvcAutoConfiguration.class,

DispatcherServletAutoConfiguration.class,

EmbeddedServletContainerAutoConfiguration.class,

ServerPropertiesAutoConfiguration.class,

HttpMessageConvertersAutoConfiguration.class

})

public class App {

image.png

2自定義boot-starter

遵循springboot官方建議對于非官方的starter命名方式為xxx-spring-boot-starter,所以本工程名為hello-spring-boot-starter。

2.1實現(xiàn)原理

我們知道使用一個公用的starter的時候,只需要將相應(yīng)的依賴添加的Maven的配置文件當(dāng)中即可,免去了自己需要引用很多依賴類,并且SpringBoot會自動進(jìn)行類的自動配置。那么 SpringBoot 是如何知道要實例化哪些類,并進(jìn)行自動配置的呢,分如下三步驟:

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

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

com.kikop.boot.HelloServiceAutoConfiguration

2.根據(jù)spring.factories配置加載AutoConfiguration類。

3.根據(jù) @Conditional注解的條件,進(jìn)行自動配置并將Bean注入Spring Context 上下文當(dāng)中。我們也可以使用@ImportAutoConfiguration({HelloServiceAutoConfiguration.class}) 指定自動配置哪些類。

2.2實現(xiàn)步驟

2.2.1創(chuàng)建maven

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>com.kikop.boot</groupId>

<artifactId>hello-spring-boot-starter</artifactId>

<version>1.0-SNAPSHOT</version>

<packaging>jar</packaging>

<dependencies>

    <!--業(yè)務(wù)系統(tǒng)中添加-->

    <!--作用是編譯時生成 spring-configuration-metadata.json ,-->

    <!--此文件主要給IDE使用。如當(dāng)配置此jar相關(guān)配置屬性在 application.yml ,-->

    <!--你可以用ctlr+鼠標(biāo)左鍵點擊屬性名,IDE會跳轉(zhuǎn)到你配置此屬性的類中。-->

    <!--<dependency>-->

        <!--<groupId>org.springframework.boot</groupId>-->

        <!--<artifactId>spring-boot-configuration-processor</artifactId>-->

        <!--<optional>true</optional>-->

    <!--</dependency>-->

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-autoconfigure</artifactId>

        <version>2.1.4.RELEASE</version>

    </dependency>

</dependencies>

<build>

    <plugins>

        <plugin>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-maven-plugin</artifactId>

        </plugin>

    </plugins>

</build>

</project>

2.2.2配置文件讀取類

package com.kikop.boot.properties;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**

  • @author kikop

  • @version 1.0

  • @project Name: hello-spring-bootstarter

  • @file Name: HelloServiceProperties

  • @desc 功能描述 配置文件讀取類

  • 對應(yīng)yml配置文件總的屬性,配置此注解可以自動導(dǎo)入application.properties配置文件中的屬性

  • @date 2020/2/20

  • @time 7:33

  • @by IDE: IntelliJ IDEA

*/

@ConfigurationProperties(prefix = HelloServiceProperties.PREFIX,ignoreUnknownFields = true)

public class HelloServiceProperties {

public static final String PREFIX = "com.kikop.boot";

// 定義jar包中默認(rèn)的配置屬性:name

private String name = "hello";

// 定義jar包中默認(rèn)的配置屬性:hobby

private String hobby = "springboot";

// 定義jar包中默認(rèn)的配置屬性:place

private String place="nj";

public String getPlace() {

    return place;

}

public void setPlace(String place) {

    this.place = place;

}

public String getName() {

    return name;

}

public void setName(String name) {

    this.name = name;

}

public String getHobby() {

    return hobby;

}

public void setHobby(String hobby) {

    this.hobby = hobby;

}

}

2.2.3業(yè)務(wù)實體類

package com.kikop.boot.entity;

import org.springframework.util.StringUtils;

/**

  • @author kikop

  • @version 1.0

  • @project Name: hello-spring-bootstarter

  • @file Name: HelloServiceInfo

  • @desc 功能描述 Starter要實現(xiàn)的功能

  • 已基于業(yè)務(wù)轉(zhuǎn)化的包裝類

  • @date 2020/2/20

  • @time 7:36

  • @by IDE: IntelliJ IDEA

*/

public class HelloServiceInfo {

//姓名

private String name;

//愛好(多個逗號分隔)

private String hobby;

//住址

private String place;

public String getPlace() {

    return place;

}

public void setPlace(String place) {

    this.place = place;

}

public String getName() {

    return "name is " + name;

}

public String getHobby() {

    return "hobby is " + hobby;

}

public void setName(String name) {

    this.name = name;

}

public void setHobby(String hobby) {

    this.hobby = hobby;

}

public String[] split(String separatorChar) {

    return StringUtils.split(this.getHobby(), separatorChar);

}

@Override

public String toString() {

    return "HelloServiceInfo{" +

            "name='" + name + '\'' +

            ", hobby='" + hobby + '\'' +

            ", place='" + place + '\'' +

            '}';

}

}

2.2.4自動配置類

package com.kikop.boot;

import com.kikop.boot.entity.HelloServiceInfo;

import com.kikop.boot.properties.HelloServiceProperties;

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;

/**

  • @author kikop

  • @version 1.0

  • @project Name: hello-spring-bootstarter

  • @file Name: HelloServiceAutoConfiguration

  • @desc 功能描述 自動配置類

  • @date 2020/2/20

  • @time 7:37

  • @by IDE: IntelliJ IDEA

*/

// 1.Configuration 表明此類是一個配置類,將變?yōu)橐粋€bean被spring進(jìn)行管理

@Configuration

// 2.當(dāng)類路徑下面有HelloServiceInfo此類時,自動配置

@ConditionalOnClass(HelloServiceInfo.class)

// 3.啟用屬性配置,將讀取 HelloServiceProperties 里面的屬性

@EnableConfigurationProperties(HelloServiceProperties.class)

//// 4.判斷指定的屬性是否具備指定的值(放類上)

//@ConditionalOnProperty(prefix = "com.kikop.boot", value = "enabled", matchIfMissing = true)

public class HelloServiceAutoConfiguration {

/**

 * 注入讀取的 HelloServiceProperties

 */

@Autowired

private HelloServiceProperties helloServiceProperties;

/**

 * 注入Bean,已基于業(yè)務(wù)轉(zhuǎn)化的包裝類

 * @return

 */

@Bean

@ConditionalOnMissingBean(HelloServiceInfo.class)

// 4.判斷指定的屬性是否具備指定的值(放Bean上)

// 當(dāng)配置文件中 com.kikop.boot.enabled=true

@ConditionalOnProperty(prefix = "com.kikop.boot", value = "enabled",matchIfMissing = true)

public HelloServiceInfo helloServiceInfo() {

    HelloServiceInfo helloServiceInfo=new HelloServiceInfo();

    helloServiceInfo.setName(helloServiceProperties.getName());

    helloServiceInfo.setHobby(helloServiceProperties.getHobby());

    helloServiceInfo.setPlace(helloServiceProperties.getPlace());

    return helloServiceInfo;

}

}

2.2.5spring.factories

文件位置:resorces\META-INF\spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

com.kikop.boot.HelloServiceAutoConfiguration

2.3測試

2.3.1加入依賴

<dependency>

<groupId>com.kikop.boot</groupId>

<artifactId>hello-spring-boot-starter</artifactId>

<version>1.0-SNAPSHOT</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-configuration-processor</artifactId>

<optional>true</optional>

</dependency>

2.3.2 controller

@Autowired

HelloServiceInfo helloServiceInfo;

@RequestMapping(value = "/hello")

public String hello() {

return helloServiceInfo.toString();

}

2.3.3 application.yml

com:

kikop:

boot:

enable: true

  name: kikop11

  hobby: tabletennis

  place: nj

2.3.4調(diào)用

http://localhost:8762/hello

HelloServiceInfo{name='kikop', hobby='tabletennis', place='nj'}

參考

  1. Springcloud

<u>https://spring.io/projects/spring-cloud</u>

<u>https://start.spring.io/</u>

  1. SpringBoot啟動過程分析

<u>http://www.itdecent.cn/p/603d125f21b3</u>

  1. SpringBoot啟動類圖

<u>https://www.processon.com/view/link/59812124e4b0de2518b32b6e</u>

  1. 使用springboot自定義starter實例1

<u>https://blog.csdn.net/qq_21150865/article/details/83504780</u>

  1. 編寫自己的SpringBoot-starter

<u>https://www.cnblogs.com/yuansc/p/9088212.html</u>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容