Spring Boot中的自定义起步依赖

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1.在pom文件添加自动配置依赖:


    org.springframework.boot
    spring-boot-autoconfigure

2.如果是某一个jar存在,才能进行配置,则需要添加上该依赖。此处添加 httpclient:


    org.apache.httpcomponents
    httpclient

3.编写默认配置类:

package com.springboot.autoconfig;

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

//在application.properties中进行配置,将覆盖下方的默认值
@ConfigurationProperties(prefix = "spring.httpclient")
public class HttpClientProperties {
    private Integer connectTimeOut = 1000;

    private Integer socketTimeOut = 10000;

    private String agent = "agent";

    private Integer maxConnPerRoute = 10;

    private Integer maxConnTotaol = 50;

    public Integer getConnectTimeOut() {
        return connectTimeOut;
    }

    public void setConnectTimeOut(Integer connectTimeOut) {
        this.connectTimeOut = connectTimeOut;
    }

    public Integer getSocketTimeOut() {
        return socketTimeOut;
    }

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

    public String getAgent() {
        return agent;
    }

    public void setAgent(String agent) {
        this.agent = agent;
    }

    public Integer getMaxConnPerRoute() {
        return maxConnPerRoute;
    }

    public void setMaxConnPerRoute(Integer maxConnPerRoute) {
        this.maxConnPerRoute = maxConnPerRoute;
    }

    public Integer getMaxConnTotaol() {
        return maxConnTotaol;
    }

    public void setMaxConnTotaol(Integer maxConnTotaol) {
        this.maxConnTotaol = maxConnTotaol;
    }
}

4.编写配置自动配置类。该类将读取之前编写的默认配置类在没有配置的情况下,创建默认配置的实例:

package com.springboot.autoconfig;

import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
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 java.io.IOException;

@Configuration//注明该类是一个Java配置类
@ConditionalOnClass({HttpClient.class})//当HttpClient存在时,才进行自动配置
@EnableConfigurationProperties(HttpClientProperties.class)//读取默认配置
public class HttpClientAutoConfiguration {

    private final HttpClientProperties properties;

    //在application.properties中进行配置,将使用其创建好的配置
    public HttpClientAutoConfiguration(HttpClientProperties properties){
        this.properties = properties;
    }

    @Bean//声明为bean,才能自动注入
    @ConditionalOnMissingBean(HttpClient.class)//当不存在创建好的HttpClient实例,将使用该方法进行创建
    public HttpClient httpClient(){
        //构建requestConfig
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(properties.getConnectTimeOut())//设置连接超时时间,默认1秒
                .setSocketTimeout(properties.getSocketTimeOut()).build();//设置读超时时间,默认10秒
        HttpClient client = HttpClientBuilder.create()
                .setDefaultRequestConfig(requestConfig) //设置requestConfig
                .setUserAgent(properties.getAgent())//设置User-Agent
                .setMaxConnPerRoute(properties.getMaxConnPerRoute())//设置一个远端IP最大的连接数
                .setMaxConnTotal(properties.getMaxConnTotaol())//设置总的连接数
                .build();
        return client;
    }

    @Bean
    @ConditionalOnBean(name="httpClient",value=HttpClient.class)//已存在HttpClient实例httpClient
    @ConditionalOnProperty(name = "spring.httpclient.testConfig", havingValue = "true")//读取配置是否设置该属性为true
    public HttpClient httpClient1(HttpClient httpClient) throws IOException {
        Long contentLength=httpClient.execute(new HttpGet("https://www.taobao.com")).getEntity().getContentLength();
        if(contentLength>10){
            System.out.println("test success..");
        }else{
            System.out.println("test fail..");
        }
        return httpClient;
    }
}

    @ConditionalOnMissingBean:若用户没有自定义某个bean,才会构建这个bean

    @ConditionalOnProperty:若用户没有开启某一个属性,则不会构建。只有开启才会构建

    @ConditionalOnClass:某个类存在的情况下,才会去构建。

 

5.编写测试类:

package com.springboot;

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SelfStarterApplicationTests {

    /**
     * 检测我们编写的自动配置HttpClientAutoConfiguration有没有生效
     */
    @Autowired
    private HttpClient httpClient;

    @Autowired
    private HttpClient httpClient1;

    /**
     * httpclient bean 的定义
     * 有三种方式都可以让HttpClientAutoConfiguration这个自动配置生效
     * 1.通过将自动配置所在package成为注解了@SpringBootApplication启动类的子package
     * 2.通过定义META-INF/spring.factories文件,里面添加EnableAutoConfiguration与自动配置的映射关系
     * 3.通过在启动类中添加注解EnableHttpClient,EnableHttpClient要@Import(HttpClientAutoConfiguration.class)
     * @return
     */
    @Test
    public void testHttclient() throws IOException {
        //访问百度,输出百度网页
        System.out.println(EntityUtils.toString(httpClient.execute(new HttpGet("http://www.baidu.com")).getEntity()));
    }

    @Test
    public void testHttclient1() throws IOException {
        //访问百度,输出百度网页
        System.out.println(EntityUtils.toString(httpClient1.execute(new HttpGet("http://www.baidu.com")).getEntity()));
    }
}

 

6.此时,由于当前package在应用程序入口类之下,所以将直接自动扫描注解@Configuration:

Spring Boot中的自定义起步依赖_第1张图片

    运行测试类方法,可以成功返回结果。

 

    若当前package不在应用程序入口类之下,也就是正常情况下,发布到外部作为第三方依赖时。此时将无法自动扫描到注解,解决方案有两个:

    方案一.创建自定义注解

package com.springboot.autoconfig;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.context.annotation.Import;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(HttpClientAutoConfiguration.class)
public @interface EnableHttpClient {
}

    在注解中,使用@Import(HttpClientAutoConfiguration.class) 引入了HttpClientAutoConfiguration 配置。此时,只需要将应用程序入口添加上自定义注解即可:

package com.springboot;

import com.springboot.autoconfig.EnableHttpClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableHttpClient
@SpringBootApplication
public class SelfStarterApplication {
    public static void main(String[] args) {
        SpringApplication.run(SelfStarterApplication.class, args);
    }
}

    方案二.创建spring.factories,定义扫描类

    spring.factories:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.springboot.autoconfig.HttpClientAutoConfiguration

    文件放在resources目录下的META-INF下:

    077f5fa92633d2ae64116ce48f4f8d56a65.jpg

 

    两者的使用辨析:

  1.     使用方案二时,在添加了依赖之后,就一定会去自动扫描配置;
  2.     使用方案一时,在添加了依赖之后,还需要在应用入口添加自定义注解才能开启自动扫描配置。

    这两种方案在实际使用过程是都有使用的。

 

7.后续操作:使用mvn命令将项目打成Jar包,添加了本地仓库,即可在其他项目引入其依赖并完成相关的自动配置:


        
            org.springframework.boot
            spring-boot-starter
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            com.springboot
            self-starter
            0.0.1-SNAPSHOT
        
    

 

    相关程序:https://gitee.com/LangWangHuangShiFu/self-starter

转载于:https://my.oschina.net/langwanghuangshifu/blog/2985838

你可能感兴趣的:(Spring Boot中的自定义起步依赖)