Skip to content

自定义springboot-starter

参考: https://www.cnblogs.com/hello-shf/p/10864977.html

使用场景

springboot的诸多starter简化了配置, 方便了使用, 在日常项目中, 若对某个技术栈有比较完善的二开和封装, 可以将相关配置提取封装成自定义的starter, 并抽取模板方法供其他模块或项目调用.

springboot-starter原理

先回顾下springboot-starter的原理:

  1. SpringBoot的 @SpringBootApplication注解, 其中包含了 @EnableAutoConfiguration自动配置注解, @EnableAutoConfiguration导入了 AutoConfigurationImportSelector.class配置文件导入的选择器
  2. AutoConfigurationImportSelector会根据 spring.factories中指定的配置类的位置去加载默认配置, 这就达到了自动配置的目的
  3. 加载配置时会有 @ConditionOnClass注解做条件控制, 若引入了某个starter使 @ConditionOnClass条件成立, 则会加载该starter对应的配置, 以达到starter的自动装配

示例: elasticsearch-spring-boot-starter

这里以es的封装为例

实现步骤:

elasticsearch-spring-boot-starter模块

依赖

Java
<?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>
        <artifactId>demo-search</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>elasticsearch-spring-boot-starter</artifactId>

    <dependencies>
        <!--es-->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.2.0</version>
        </dependency>

        <!--使用xml或property配置-->
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-configuration-processor</artifactId>-->
<!--            <optional>true</optional>-->
<!--            <version>2.1.3.RELEASE</version>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>
    </dependencies>
</project>

引入es配置

ElasticsearchConfigProperty

Java
@ConfigurationProperties(prefix = "elasticsearch")
public class ElasticsearchConfigProperty {

    private String httpHost;
    private Integer connectionTimeOut;
    private Integer socketTimeOut;
    private Integer connectionRequestTimeOut;

    public String getHttpHost() {
        return httpHost;
    }

    public void setHttpHost(String httpHost) {
        this.httpHost = httpHost;
    }

    public Integer getConnectionTimeOut() {
        return connectionTimeOut;
    }

    public void setConnectionTimeOut(Integer connectionTimeOut) {
        this.connectionTimeOut = connectionTimeOut;
    }

    public Integer getSocketTimeOut() {
        return socketTimeOut;
    }

    public void setSocketTimeOut(Integer socketTimeOut) {
        this.socketTimeOut = socketTimeOut;
    }

    public Integer getConnectionRequestTimeOut() {
        return connectionRequestTimeOut;
    }

    public void setConnectionRequestTimeOut(Integer connectionRequestTimeOut) {
        this.connectionRequestTimeOut = connectionRequestTimeOut;
    }
}

ElasticsearchConfig

Java
@Configuration
@EnableConfigurationProperties(ElasticsearchConfigProperty.class)
@ConditionalOnProperty(prefix = "elasticsearch", name = "enable", havingValue = "true")
public class ElasticsearchConfig {

    @Autowired
    private ElasticsearchConfigProperty elasticsearchConfigProperty;

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        RestClientBuilder builder = RestClient.builder(HttpHost.create(elasticsearchConfigProperty.getHttpHost()));
        builder.setRequestConfigCallback(requestConfigBuilder -> {
            if(elasticsearchConfigProperty.getConnectionTimeOut()!=null){
                requestConfigBuilder.setConnectTimeout(elasticsearchConfigProperty.getConnectionTimeOut());
            }
            if(elasticsearchConfigProperty.getSocketTimeOut()!=null){
                requestConfigBuilder.setSocketTimeout(elasticsearchConfigProperty.getSocketTimeOut());
            }
            if(elasticsearchConfigProperty.getConnectionRequestTimeOut()!=null){
                requestConfigBuilder.setConnectionRequestTimeout(elasticsearchConfigProperty.getConnectionRequestTimeOut());
            }
            return requestConfigBuilder;
        });
        return new RestHighLevelClient(builder);
    }

}

提供ElasticsearchTemplate模板接口

Java
public interface ElasticsearchTemplate {
    SearchResponse search(String index, int page, int pageSize, SearchSourceBuilder queryBuilder)
            throws IOException;
}
Java
@Service
public class ElasticsearchTemplateImpl implements ElasticsearchTemplate {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public SearchResponse search(String index, int page, int pageSize, SearchSourceBuilder sourceBuilder)
            throws IOException {
        sourceBuilder.from((page - 1) * pageSize).size(pageSize);
        SearchRequest request = new SearchRequest(index);
        request.source(sourceBuilder);
        return restHighLevelClient.search(request, RequestOptions.DEFAULT);
    }
}

注册配置

在resources/META-INF下建文件spring.factories

Java
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
 org.example.elasticsearch.spring.boot.starter.config.ElasticsearchConfig

调用示例: demo-search-service

依赖及配置

Java
<dependency>
    <groupId>org.example</groupId>
    <artifactId>elasticsearch-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
Java
elasticsearch:
  enable: true
  httpHost: http://39.106.55.179:40009

使用

1744858389318