Spring Boot 必備技能之Starter自定義

本文摘自於 《Spring Cloud微服務 入門 實戰與進階》 一書。java

Spring Boot的方便體如今簡化了不少繁瑣的配置,對開發人員來講是一個福音,經過引入各類Spring Boot Starter包能夠快速的搭建出一個項目的腳手架。web

目前提供的Spring Boot Starter包有:redis

  • spring-boot-starter-web:快速構建基於Spring MVC的Web項目,使用Tomcat作默認嵌入式容器。spring

  • spring-boot-starter-data-redis:操做Redis。sql

  • spring-boot-starter-data-mongodb:操做Mongodb。mongodb

  • spring-boot-starter-data-jpa:操做Mysql。json

  • spring-boot-starter-activemq:操做Activemq。bash

  • 等等......app

自動配置很是方便,當咱們要操做Mongodb的時候,只須要引入spring-boot-starter-data-mongodb的依賴,而後配置Mongodb的連接信息 spring.data.mongodb.uri=mongodb://localhost/test就可使用MongoTemplate來操做數據,MongoTemplate的初始化工做所有交給Starter來完成。異步

自動配置麻煩的是當出現錯誤時,排查問題的難度上升了。自動配置的邏輯都在Spring Boot Starter中,要快速的可以定位問題,那麼你必須得了解Spring Boot Starter的內部原理。接下來咱們本身動手來實現一個Spring Boot Starter。

開發Starter步驟:

  • 建立Starter項目

  • 定義Starter須要的配置(Properties)類

  • 編寫自動配置類

  • 編寫spring.factories文件加載自動配置類

  • 編寫配置提示文件spring-configuration-metadata.json(不是必須的)

建立一個項目spring-boot-starter-demo,Pom.xml配置以下:

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
		<optional>true</optional>
	</dependency>
</dependencies>
複製代碼

建立一個配置類,用於在屬性文件中配置值,至關於spring.data.mongo這種形式

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

@Data
@ConfigurationProperties("spring.user")
public class UserPorperties {

	private String name;
	
}
複製代碼

@ConfigurationProperties指定了配置的前綴,也就是spring.user.name=XXX

再定義一個Client,至關於MongoTemplate,裏面定一個方法,用於獲取配置中的值

public class UserClient {

	private UserPorperties userPorperties;
	
	public UserClient() {
		
	}
	
	public UserClient(UserPorperties p) {
		this.userPorperties = p;
	}
	
	public String getName() {
		return userPorperties.getName();
	}
	
}

複製代碼

一個最基本的Starter包定義好了,但目前確定是不能使用UserClient ,由於咱們沒有去自動構建UserClient 的實例,接下來開始構建UserClient

@Configuration
@EnableConfigurationProperties(UserPorperties.class)
public class UserAutoConfigure {

	@Bean
	@ConditionalOnProperty(prefix = "spring.user",value = "enabled",havingValue = "true")
	public UserClient userClient(UserPorperties userPorperties) {
		return new UserClient(userPorperties);
	}
	
}
複製代碼

Spring Boot會默認掃描跟啓動類平級的包,若是咱們的Starter跟啓動類不在同一個主包下,如何讓UserAutoConfigure 生效?

第一種方式:

在resources下建立一個META-INF文件夾,而後在META-INF文件夾中建立一個spring.factories文件,文件中指定自動配置的類

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.cxytiandi.demo.UserAutoConfigure
複製代碼

Spring Boot啓動時會去讀取spring.factories文件,而後根據配置激活對應的配置類,到底爲止就簡單的實現了一個Starter包。

如今能夠在其餘的項目中引入這個Starter包:

<dependency>
	<groupId>com.example</groupId>
	<artifactId>spring-boot-starter-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
</dependency>
複製代碼

引入以後就直接可使用UserClient,UserClient 在項目啓動的時候已經自動初始化好。

@RestController
public class UserController {
	
	@Autowired
	private UserClient userClient;
	
	@GetMapping("/user/name")
	public String getUserName() {
		return userClient.getName();
	}
	
}
複製代碼

不少時候咱們不想引入了Starter包就執行初始化的邏輯,想要用戶來指定是否要開啓Starter包的自動配置功能,好比經常使用的@EnableAsync這個註解就是用於開啓調用方法異步執行的功能。

一樣的咱們也能夠經過註解的方式來開啓是否自動配置,若是用註解的方式,那麼spring.factories就不須要編寫了,下面來看怎麼定義啓用自動配置的註解。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({UserAutoConfigure.class})
public @interface EnableUserClient {

}
複製代碼

核心是@Import({UserAutoConfigure.class})這行代碼,經過導入的方式實現把UserAutoConfigure實例加入SpringIOC容器中,這樣就能開啓自動配置了。

使用方式就是在啓動類上加上該註解,代碼入下:

@EnableUserClient
@SpringBootApplication
public class SpringBootDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootDemoApplication.class, args);
	}
}

複製代碼

在某些場景下,UserAutoConfigure中會配置多個對象,對於這些對象,不想所有配置,也想讓用戶指定須要開啓配置的時候再去構建對象,這個時候咱們能夠經過@ConditionalOnProperty來指定是否開啓配置的功能,代碼以下:

@Bean
@ConditionalOnProperty(prefix = "spring.user",value = "enabled",havingValue = "true")
public UserClient userClient(UserPorperties userPorperties) {
	return new UserClient(userPorperties);
}
複製代碼

經過上面的配置,只有當啓動類加了@EnableUserClient而且配置文件中spring.user.enabled=true的時候纔會自動配置UserClient 。

在自定義Starter包的過程當中,還有一點也比較重要,就是須要對配置的內容項進行提示,須要注意的是Eclipse中是不支持提示的,我用的Spring Tools 4 for Eclipse,以下圖:

搜狗截圖20181122152845.png

定義提示內容須要在META-INF中建立一個spring-configuration-metadata.json

{
  "properties": [
    {
      "name": "spring.user.name",
      "defaultValue": "cxytinadi"
    },
    {
      "name": "spring.user.enabled",
      "type": "java.lang.Boolean",
      "defaultValue": false
    }
  ]
}
複製代碼
  • name:配置名
  • type:配置的數據類型
  • defaultValue:默認值

本文摘自於 《Spring Cloud微服務 入門 實戰與進階》 一書。

猿天地
相關文章
相關標籤/搜索