Springboot系列-自定義starter

Springboot系列-自定義starter

前言:用過springboot的各位應該都知道,Springboot相對於Spring/SpringMVC要方便的多,爲什麼呢?這主要還是歸功於Starter,其實Starter也是基於Spring/SpringMVC基礎上實現的,因爲Starter帶來了許多的自動化配置,所以在我們開發的時候省了不少力

理解Starter

那麼Starter是基於什麼才能夠實現衆多自動化配置的呢?其實Starter的核心註解就是@Conditional,當classpath下面存在某一個class時,這個配置纔會生效


自定義Starter

定義Starter

1.首先創建一個普通的新的maven項目,創建完成之後添加Starter的自動化配置類如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
    <version>2.1.8.RELEASE</version>
</dependency>

配置完之後其實我們可以通過源碼看到,好多自動化配置已經引入進來了
在這裏插入圖片描述

2.配置完成之後創建一個DemoProperties類,用來接收application.properties中注入的值,如下:

@ConfigurationProperties(prefix = "test")
public class DemoProperties {
    private String name = "王先森";
    private String hobby = "Coding";

    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;
    }
}

以上這個DemoProperties配置類的意思就是直接將application.properties裏面的屬性值注入到該實例中,@ConfigurationProperties 類型安全的屬性注入,即將 application.properties 文件中前綴爲 javaboy 的屬性注入到這個類對應的屬性上

application.prpoerties配置文件內容如下:

test.name = wxy
test.hobby = basketball

3.配置完DemoProperties之後,在定義一個DemoService類並定義個方法如下:

public class DemoService {
    private String name;
    private String hobby;

    public String doSomething() {
        return name + " do " + hobby + " !";
    }

    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;
    }
}

上面這個DemoService意思就是很簡單的一個類,添加了個doSomething方法,之後再對應文件將該類注入之後,傳入屬性值調用該方法

4.接下來要做的是非常關鍵,就是關於自動配置的定義,因爲之前我們可能用的都是別人定義的,所以這次需要自己去定義

@Configuration
@EnableConfigurationProperties(DemoProperties.class)
@ConditionalOnClass(DemoService.class)
public class DemoServiceAutoConfiguration {

    @Autowired
    DemoProperties demoProperties;

    @Bean
    DemoService demoService(){
        DemoService demoService = new DemoService();
        demoService.setName(demoProperties.getName());
        demoService.setHobby(demoProperties.getHobby());
        return demoService;
    }
}

針對以上一段自動配置,解釋如下:

  • Configuration:表示這是一個配置類
  • EnableConfigurationProperties:此註解是爲了使之前配置的@ConfigurationProperties 生效
  • @ConditionalOnClass :表示項目當前classpath下存在DemoService時,後面的配置纔會生效
  • 自動配置類中首先注入 DemoProperties ,該實例中有在 application.properties 中配置的相關數據
  • 提供一個 DemoService 的實例,將 DemoProperties 中的值注入進去

5.自動化配置類基本完成,接下來還需要一個 spring.factories 文件,那麼這個文件是幹什麼用的呢?我們知道Springboot項目中有一個啓動類,該啓動類包含了@SpringBootApplication 註解,這個註解的定義如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {}

根據上面我們可以看出其實SpringBootApplication 是一個組合註解,它包含了如上註解,其最重要和關鍵的三個註解並解釋如下:

  • @SpringBootConfiguration:此註解爲Springboot配置註解,如下又在該註解中又包含如下註解:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
  • @EnableAutoConfiguration:開啓自動配置註解,只有開啓了這個自動配置之後自動配置纔會生效,其註解又包含如下註解:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
  • @ComponentScan:這個註解在有一個主要的功能就是配置註解掃描,可以自定義去配置掃描的範圍

6.在 Maven 項目的 resources 目錄下創建一個名爲 META-INF 的文件夾,然後在文件夾中創建一個名爲 spring.factories 的文件,文件內容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.wxy.entity.DemoServiceAutoConfiguration

動化配置類的路徑配置完成,如此之後我們的自動化配置類就算完成了

本地安裝

我們將我們寫好的Starter項目進行打包,如下:

在這裏插入圖片描述

雙擊完成後,這個 Starter 就安裝到我們本地倉庫了,其實這個時候我們從該路徑可以發現他打包成了一個jar包,如下:
在這裏插入圖片描述
那麼如何使用它呢?


使用Starter

新建一個普通的 Spring Boot 工程,創建成功之後,加入自定義 Starter 的依賴,如下:

<dependency>
    <groupId>com.example</groupId>
    <artifactId>emptyMavenProject</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

此時我們引入了上面自定義的 Starter ,也就是說項目中現在有一個默認的 DemoService 實例可以使用,關於此實例的數據,可以在 application.properties 中進行配置,如下:

test.name = Wang sir
test.hobby = Coding

配置完成後,可選擇在單元測試方法中注入 DemoSerivce 實例來使用,代碼如下:

@SpringBootTest(classes = App.class)
class TeststarterApplicationTests {

    @Autowired
    DemoService demoService;
    @Test
    public void contextLoads() {
        System.out.println(demoService.doSomething());
    }
}

執行運行結果如下:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.1.RELEASE)
2019-12-03 15:16:57.423  INFO 19712 --- [           main] c.e.t.TeststarterApplicationTests        : Starting TeststarterApplicationTests on Wangxinyao with PID 19712 (started by Administrator in E:\IDEAWorkSpace\teststarter)
2019-12-03 15:16:57.430  INFO 19712 --- [           main] c.e.t.TeststarterApplicationTests        : No active profile set, falling back to default profiles: default
2019-12-03 15:17:00.216  INFO 19712 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-12-03 15:17:00.754  INFO 19712 --- [           main] c.e.t.TeststarterApplicationTests        : Started TeststarterApplicationTests in 4.157 seconds (JVM running for 6.18)
Wang sir do Coding !
2019-12-03 15:17:01.054  INFO 19712 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'

結語:基本上對於自定義Starter配置的講解就到這裏了,通過自定義Starter,可以把之前的項目通過打包注入到新的項目中,便捷開發

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章