SpringBoot封裝咱們本身的Starter

點擊上方「Java面試進化論」,選擇「設爲星標html

回覆」666「獲取新整理的面試資料vue

原文 : https://juejin.im/post/6844903923162038279java


SpringBoot中starter真是個好東西,不論是官方提供,仍是自定義,快速集成,真方便!web

日常咱們使用 SpringBoot 開發常常用到一些第三方 jar 包,並且一般只是引入一個xxx-starterjar 包就擁有了全部功能,到底其中的原理是怎樣的呢?要想知道其中的原理,咱們不妨先本身手動製做一個Starter,這對咱們深刻使用一些第三框架將會有至關大的幫助。
面試

1、SpringBoot Starter 開發規範

SpringBoot 官網文檔提到的規範大體由下面幾個:spring

  • 一、命名使用spring-boot-starter-xxx, 其中xxx是咱們具體的包名稱,若是集成Spring Cloud則使用spring-cloud-starter-xxxsql

  • 二、一般須要準備兩個jar文件,其中一個不包含任何代碼,只用於負責引入相關以來的 jar 文件,另一個則包含核心的代碼後端

nacos與 Spring Cloud 集成的 starter 以下圖:springboot

更多Starter製做規範,咱們能夠查看官網文檔https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#boot-features-custom-starter微信

2、Starter 開發開發步驟

首先咱們應該先明白 Springboot 加載第三方Starter的機制,詳情請參考小編的另一篇文章 SpringBoot 啓動源碼分析及相關技巧學習

  • 一、新建一個Maven工程,咱們起名爲study-spring-boot-starter

  • 二、引入相關的依賴

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<!-- 咱們是基於Springboot的應用 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

由於咱們須要用到 Springboot 提供的相關注解,而且使用 springboot 提供的自動配置功能,咱們不得不引入spring-boot-autoconfigurespring-boot-dependencies兩個依賴。

搜索公縱號:MarkerHub,關注回覆[ vue ]獲取先後端入門教程

  • 三、新建咱們本身的自動配置類

通常來講,咱們可能想在 springboot 啓動的時候就預先注入本身的一些 bean,此時,咱們要新建本身的自動配置類,通常採用xxxxEnableAutoConfiguration

下面咱們新建StudyStarterAutoConfiguration.java

package com.example.mystarter.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.example.mystarter.other.Student;

/**
* 存放咱們的配置類,用來配置咱們自定義的bean的。既然是一個配置類,那麼咱們就須要有@Configuration進行聲明
*
* @Author jiawei huang
* @Since 2019年8月23日
* @Version 1.0
*/

@Configuration
// 導入咱們自定義的配置類,供當前類使用
@EnableConfigurationProperties(StudentConfigProperties.class)
// 當存在某個類時,此自動配置類纔會生效,這裏可使用外部的String類名
@ConditionalOnClass(Student.class)
// 只有web應用程序時此自動配置類纔會生效
@ConditionalOnWebApplication
public class StudyStarterAutoConfiguration {
/**
* 當存在study.config.enable=true的配置時,這個Student bean才生效
*
* @return
*/

@Bean
@ConditionalOnProperty(prefix = "study.config", name = "enable", havingValue = "true")
public Student defaultStudent(StudentConfigProperties studyConfigProperties) {
Student student = new Student();
student.setAge(studyConfigProperties.getAge());
student.setName(studyConfigProperties.getName());
return student;
}
}

@Configuration聲明該類爲一個配置類

@EnableConfigurationProperties的意思是,將括號內所指定的類注入容器成爲一個 bean 對象,由於通常來講,像 springboot 默認的包掃描路徑爲xxxxxxApplication.java所在包以及其全部子包, 可是一些第三方的 jar 中的 bean 很明顯不能被掃描到,此時該註解就派上了用場,固然,你可能會說,我使用@ComponentScan不就好了,這兩個註解的區別是:@ComponentScan前提是你要的 bean 已經存在 bean 容器中了,而@EnableConfigurationProperties是要讓容器自動去發現你要類並註冊成爲 bean。

springboot 提供了不少的@Condition開頭的註解,用於表示當某某條件成立或者不成立時所作的操做。

@ConditionalOnClass指的是當存在某個類時,此自動配置類StudyStarterAutoConfiguration纔會生效, 咱們可能會問,咱們有時候想依賴一個第三方的 bean 存在,StudyStarterAutoConfiguration才生效怎麼辦(好比mybatisstarter源碼須要sqlsessionfactorybean同樣),不用慌,@ConditionalOnClass也容許咱們指定字符串全路徑,例如@ConditionalOnClass("com.xxx.xxx")

@ConditionalOnWebApplication 表示噹噹前應用是一個 web servlet 應用時,配置類才生效。這也能夠解答爲何 springboot 源碼SpringApplication.java中有作應用推斷。

@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 這裏會去作推斷
this.webApplicationType = WebApplicationType.deduceFromClasspath();
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}

  • 四、咱們新建一個StudentConfigProperties.java,聲明該 starter 的使用者能夠配置哪些配置項。

package com.example.mystarter.config;

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

/**
* 配置項
*
* @Author jiawei huang
* @Since 2019年8月23日
* @Version 1.0
*/

@ConfigurationProperties(prefix = "study.config")
public class StudentConfigProperties {
private int age;

private String name;

/**
* @return the age
*/

public int getAge() {
return age;
}

/**
* @param age the age to set
*/

public void setAge(int age) {
this.age = age;
}

/**
* @return the name
*/

public String getName() {
return name;
}

/**
* @param name the name to set
*/

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "StudentConfigProperties [age=" + age + ", ]";
}
}

  • 五、在resources目錄下新建一個META-INF目錄而且建立一個spring.factories文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.mystarter.config.StudyStarterAutoConfiguration

咱們的自動配置入口類,Springboot 會掃描到這個文件,掃描機制能夠查看小編寫的另一篇博文

3、使用咱們本身的Starter

  • 一、咱們新建另一個 springboot 工程,引入剛剛的starter

<dependency>
<groupId>com.example</groupId>
<artifactId>study</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

咱們新建一個接口,來測試咱們的 starter 是有有用,代碼以下:

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.mystarter.config.StudentConfigProperties;
import com.example.mystarter.other.Student;

/**
*
* @Author jiawei huang
* @Since 2019年8月19日
* @Version 1.0
*/

@RestController
public class MyController {

@Autowired
private Student student;

@Autowired
private StudentConfigProperties studentConfigProperties;

@RequestMapping("/getStudent")
private String getStudent() {
return "name=[" + student.getName() + "],age=[" + student.getAge() + "],studentConfigProperties=["
+ studentConfigProperties + "]";
}

}

啓動咱們的 demo 工程,而後訪問咱們的接口,結果以下:

好了,咱們的 starter 製做到此就結束了,其實很是簡單,我建議在學會製做的基礎上,多看看其餘框架的源碼加以驗證,最好可以也動手實現如下,說不定之後咱們也須要提供一個 starer 給其餘人用呢。有疑問,歡迎評論區交流,謝謝閱讀。


1.  面試官 : 如何使用 StringBuider 效率更高?

2.  還不懂Spring Boot啓動原理的話,必定要看看!

3.  面試官 : TCP 鏈接上面能發多少個 HTTP 請求?

4. NullPointerException 的處理新方式, Java14 真的太香了!

5. 華爲阿里下班時間曝光:全部的光鮮,都有加班的味道


    
       
       
        
        
                 
        
    
       
回覆"SpringCrm"獲取

SpringBoot 後臺 CRM 項目


   
      
      
       
       
                
       
   
      
好文點個在看吧!

本文分享自微信公衆號 - Java面試進化論(AuditionEvolution)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索