1. 程式人生 > >SpringBoot之自定義Starter及AutoConfiguration

SpringBoot之自定義Starter及AutoConfiguration

現在微服務化是大趨勢,因為現在伴隨著移動網際網路的快速發展,快速上線,快速更新等需求越來越多,所以雲平臺營運而來,從Docker在到Kubernate,微服務逐漸成為了現代軟體開發的新寵。說道微服務,我們就要說一下,微服務需要哪些服務來支撐,為什麼選擇SpringBoot,微服務化因為服務粒度足夠小,所以需要將多個服務進行組合來完成具體的一個業務,但是也伴隨著問題而來,服務間的呼叫依賴,如果服務不可用就會出現問題,如果網路頻寬不足,效能也會大打折扣,同時當多個服務依次呼叫的時候,整個鏈路異常定位同樣很難,現在非同步操作隨處可見,好不容易業務跑通了,發現配置變更,不可能執行中的所有伺服器都更改一下在重啟吧,統一的配置管理迫在眉睫,最後關鍵的服務註冊與發現不得不上,你不可能新增一個服務就維護一個IP和埠和URI吧。所以通過剛才的簡述,學習過微服務的同學可能就已經能明白微服務需要哪些東西了,需要的東西很多,SpringBoot和SpringCloud提供了一站式解決方案,所以很多東西不需要自己再去實現就可以直接使用,因為微服務的逐步上線及業務拆分是需要一個長期的過程的,畢竟一個優質可靠的框架不是靠一次設計就可以完善的,也不是說SpingCloud就一定是最好的,通過入門,我們之後再使用過程中可以積累經驗,再創造適合自己的微服務框架也未嘗不可,好了今天就先說說微服務具體都有啥吧。微服務幾個核心的部件分別是服務註冊與發現,分散式配置管理,訊息匯流排,熔斷及降級,服務間呼叫Feign,效能監控,服務閘道器等。今天我們先說說微服務最基礎的框架SpringBoot。

SpringBoot是一套具有現代思想,為了完全解脫複雜配置而設計的快速開發框架,他提供了很多Enable*註解,只要使用對應的註解就會自動生成相應的配置檔案,是不是很神奇,而且SpringBoot使用統一的配置檔案application.properties,我們只需要在配置檔案中定義必須的引數即可,然後我們就可以去開發我們的業務邏輯擼程式碼去了,是不是很爽。做過開發有幾年的同志一定對開發環境的配置和搭建苦惱不已,往往大家都是更熱衷於擼程式碼搞開發,而不是去搞環境,玩配置。因為環境往往不是天天搭建,而一整套環境搭建起來又非常複雜,所以Spring為了解決在程式碼中的配置就創造了SpringBoot,SpringBoot中包含了一個包AutoConfiguration,這個包專門用來處理配置相關管理,Spring已經封裝了大部分主流的框架,單這還不夠,作為一個專業擼程式碼的,自己做的程式碼怎麼也能自動配置呢?這個很關鍵啊,是不是,也許有的人說了,提供的工具足夠了啊,為什麼還要自己開發呢?哈哈,這就說明了你還很嫩,還沒有達到一定的高度,這裡我不是說我是大牛,只是說明了一個態度,作為一個專業人員,一套框架的核心原理及精髓,我們還是需要去深入學習的,好了,說了半天也該來電乾貨了,先上程式碼,在根據程式碼詳細說明。

為了開發自定義的Starter我們需要引入依賴spring-boot-autoconfigure,這個依賴是必須要引入的依賴,其他的依賴可以根據需要進行新增,接下來是spring-boot-configuration-processor,這個依賴也是必須要引入的,但是有個前提,那就是當你需要配置檔案的時候@ConfigurationProperties(prefix = "spring.mystarter"),你就必須引入。

<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.easy.starter</groupId>
	<artifactId>MyStarter</artifactId>
	<version>1.0.0</version>
	<packaging>jar</packaging>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-autoconfigure</artifactId>
			<version>2.0.4.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<version>2.0.4.RELEASE</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>MyStarter</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>
package com.easy.app.properties;

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

@ConfigurationProperties(prefix = "spring.mystarter")
public class MyProperties {
	private String msg = "This is a starter Demo!";
	private boolean show = true;

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public boolean isShow() {
		return show;
	}

	public void setShow(boolean show) {
		this.show = show;
	}
}
package com.easy.app.config;

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;

import com.easy.app.properties.MyProperties;
import com.easy.app.service.MyService;

@Configuration
@EnableConfigurationProperties(MyProperties.class)
@ConditionalOnClass(MyService.class)
@ConditionalOnProperty(prefix = "mystarter", value = "enabled", matchIfMissing = true)
public class MyConfiguration {
	@Autowired
	private MyProperties myProperties;

	@Bean
	@ConditionalOnMissingBean(MyService.class)
	public MyService helloService() {
		MyService myService = new MyService();
		myService.setMsg(myProperties.getMsg());
		myService.setShow(myProperties.isShow());
		return myService;
	}

}
package com.easy.app.service;

public class MyService {
	private String msg;
	private boolean show = true;

	public String sayHello() {
		return show ? "Hello," + msg : "Hidden";
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public void setShow(boolean show) {
		this.show = show;
	}
}

 下面的這段程式碼是開啟自動配置的核心配置,是告訴Spring那個類是是自動配置的配置類。在src/main/resources下建立路徑/META-INF/spring-factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.easy.app.config.MyConfiguration

 雖然現在有了自動配置,但是我們還是需要在application.properties中配置引數,但是沒有提示怎麼辦,沒問題我們同樣有辦法,同樣在src/main/resources下建立路徑/META-INF/spring-configuration-metadata.json,配置好之後,我們在使用的時候就會出現配置了。

{
  "hints": [],
  "groups": [
    {
      "sourceType": "com.easy.app.properties.MyProperties",
      "name": "spring.mystarter",
      "type": "com.easy.app.properties.MyProperties"
    }
  ],
  "properties": [
    {
      "sourceType": "com.easy.app.properties.MyProperties",
      "name": "spring.mystarter.msg",
      "type": "java.lang.String"
    },
    {
      "sourceType": "com.easy.app.properties.MyProperties",
      "name": "spring.mystarter.show",
      "type": "java.lang.Boolean"
    }
  ]
}