一.Spring Boot Starter简介
Starter是Spring Boot中的一个非常重要的概念,Starter相当于模块,它能将模块所需的依赖整合起来并对模块内的Bean根据环境( 条件)进行自动配置。使用者只需要依赖相应功能的Starter,无需做过多的配置和依赖,Spring Boot就能自动扫描并加载相应的模块。
总结:
1.它整合了这个模块需要的依赖库;
2.提供对模块的配置项给使用者;
3.提供自动配置类对模块内的Bean进行自动装配;
例如,在Maven的依赖中加入spring-boot-starter-web就能使项目支持Spring MVC,并且Spring Boot还为我们做了很多默认配置,无需再依赖spring-web、spring-webmvc等相关包及做相关配置就能够立即使用起来。
二.Starter的开发步骤
编写Starter非常简单,与编写一个普通的Spring Boot应用没有太大区别,总结如下:
1.新建Maven项目,在项目的POM文件中定义使用的依赖;
2.新建配置类,写好配置项和默认的配置值,指明配置项前缀;
3.新建自动装配类,使用@Configuration和@Bean来进行自动装配;
4.新建spring.factories文件,指定Starter的自动装配类;
三.Starter的开发示例
下面,我就以创建一个自动配置并连接ElasticSearch的Starter来讲一下各个步骤及细节。
1.新建Maven项目,在项目的POM文件中定义使用的依赖。
<?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"> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.4.RELEASE</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>es-starter</artifactId> <version>1.0.0.SNAPSHORT</version> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.18</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.0.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>x-pack-transport</artifactId> <version>5.6.4</version> </dependency> </dependencies> </project>
由于本starter主要是与ElasticSearch建立连接,获得TransportClient对象,所以需要依赖
x-pack-transport
包。
2.新建配置类,写好配置项和默认的配置值,指明配置项前缀。
package cn.sxw.commons.data.es.starter; import org.springframework.boot.context.properties.ConfigurationProperties; import lombok.Data; /** * Created by William on 2018/8/7. */ @Data @ConfigurationProperties(prefix = "sxw.elasticsearch") public class ElasticSearchProperties { private String clusterName = "elasticsearch"; private String clusterNodes = "127.0.0.1:9300"; private String userName = "elastic"; private String password = "changeme"; }
指定配置项前缀为
sxw.elasticsearch
,各配置项均有默认值,默认值可以通过模块使用者的配置文件进行覆盖。
3.新建自动装配类,使用@Configuration
和@Bean
来进行自动装配。
package cn.sxw.commons.data.es.starter; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.xpack.client.PreBuiltXPackTransportClient; import org.springframework.beans.factory.DisposableBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; import java.util.stream.Collectors; import javax.annotation.Resource; import lombok.extern.slf4j.Slf4j; /** * Created by William on 2018/8/7. */ @Slf4j @Configuration @EnableConfigurationProperties(ElasticSearchProperties.class) public class ElasticSearchAutoConfiguration implements DisposableBean{ private TransportClient transportClient; @Resource private ElasticSearchProperties properties; @Bean @ConditionalOnMissingBean(TransportClient.class) public TransportClient transportClient() { log.debug("=======" + properties.getClusterName()); log.debug("=======" + properties.getClusterNodes()); log.debug("=======" + properties.getUserName()); log.debug("=======" + properties.getPassword()); log.info("开始建立es连接"); transportClient = new PreBuiltXPackTransportClient(settings()); TransportAddress[] transportAddresses= Arrays.stream(properties.getClusterNodes().split(",")).map (t->{ String[] addressPortPairs = t.split(":"); String address = addressPortPairs[0]; Integer port = Integer