Spring Boot中的自定義起步依賴
阿新 • • 發佈:2018-12-09
1.在pom檔案新增自動配置依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency>
2.如果是某一個jar存在,才能進行配置,則需要新增上該依賴。此處新增 httpclient:
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency>
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:
執行測試類方法,可以成功返回結果。
若當前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下:
兩者的使用辨析:
- 使用方案二時,在添加了依賴之後,就一定會去自動掃描配置;
- 使用方案一時,在添加了依賴之後,還需要在應用入口新增自定義註解才能開啟自動掃描配置。
這兩種方案在實際使用過程是都有使用的。
7.後續操作:使用mvn命令將專案打成Jar包,添加了本地倉庫,即可在其他專案引入其依賴並完成相關的自動配置:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.springboot</groupId> <artifactId>self-starter</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies>