不學無數——SpringBoot入門Ⅶ

SpringBoot

1.建立本身的Auto-configuration

不管是在公司中你想開發本身的一套框架,定製一些東西,或者是在開源網站中分享本身作的一些東西。你可能想要開發屬於本身的Auto-configuration。Auto-configuration的類可以捆綁到外部的jar包中,而且被SpringBoot進行使用。例如咱們常用的@Autowire註解會自動的注入一個實例到Spring的容器中,這時咱們被注入進來的類必須有個註解進行標註,例如:@Service、@Controller等等。可是對於在jar包中的類的話,考慮的須要多一些,例如須要考慮在注入時我會依賴到誰,誰先進行注入等等。java

Auto-configuration一般是和starter聯繫起來的,一個官網提供的小例子展現瞭如何一步一步建立屬於本身的startergit

1.1 理解Auto-configured類

在底層代碼中,Auto-configured是被@Configuration註解的類實現的。另外@Conditional註解被用來限制何時Auto-configured應該被應用。一般來講,Auto-configured的類使用@ConditionalOnClass@ConditionalOnMissingBean這兩個註解,這是爲了確保 auto-configuration 只在一些相關的類生效之後纔會加載@Configuration類。github

你也能夠經過瀏覽SpringBoot-autoConfigure由Spring提供的@Configuration類。web

1.2 Auto-configuration的目錄結構

SpringBoot會檢查全部jar包中的META-INF/spring.factories文件,在這個文件中應該列出了key是EnableAutoConfiguration value是想要配置的類,例以下:spring

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration

固然也可使用 @AutoConfigureAfter@AutoConfigureBefore兩個註解進行標識想要哪一個類進行先加載。例如想要提供一個特定的web配置,那麼你的類應該在WebMvcAutoConfiguration以後加載。數據庫

如何想要auto-configurations的類進行順序的加載,那麼可使用@AutoConfigureOrder註解進行排序。app

Auto-configurations僅僅可以被這種方式進行加載,實際上,他們不會被包掃描進行加載。框架

1.3 Condition註解

SpringBoot利用@Condition註解來肯定是否是要建立Bean實例ide

在所開發的對外封裝jar包中可能會使用一個或者多個的@Condition註解在自動配置的類中。@ConditionalOnMissingBean註解會覆蓋掉你的默認配置。spring-boot

SpringBoot包括許多的@Conditional的註解,你可以重複使用它在類中或者單獨的@Bean方法上。這些註解包括

  • Class Conditions
  • Bean Conditions
  • Property Conditions
  • Resource Conditions
  • Web Application Conditions

1.3.1 Class Conditions

  • @ConditionalOnClass: 某個class位於類路徑上,纔會實例化一個Bean。該註解的參數對應的類必須存在,不然不解析該註解修飾的配置類。這個頗有用的,好比不一樣的jar包之間有依賴,若是依賴的類不存在的話,那麼就會直接跳過,不會報錯。
  • @ConditionalOnMissingBean:僅僅在當前上下文中不存在某個對象時,纔會實例化一個Bean。該註解表示,若是存在它修飾的類的bean,則不須要再建立這個bean,能夠給該註解傳入參數例如@ConditionOnMissingBean(name = "example"),這個表示若是name爲「example」的bean存在,這該註解修飾的代碼塊不執行

1.3.2 Bean Conditions

  • @ConditionalOnBean:僅僅在當前上下文中存在某個對象時,纔會實例化一個Bean
  • @ConditionalOnMissingBean:僅僅在當前上下文中不存在某個對象時,纔會實例化一個Bean

舉例以下:

@Configuration
public class MyAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean
	public MyService myService() { ... }

}

1.3.3 Property Conditions

  • @ConditionalOnProperty:這個註解可以控制某個configuration是否生效。具體操做是經過其兩個屬性name以及havingValue來實現的,其中name用來從application.properties中讀取某個屬性值,若是該值爲空,則返回false;若是值不爲空,則將該值與havingValue指定的值進行比較,若是同樣則返回true;不然返回false。若是返回值爲false,則該configuration不生效;爲true則生效。

1.3.4 Resource Conditions

  • @ConditionalOnResource註解容許只有在特定資源出現時配置纔會生效。資源可使用常見的Spring約定命名,例如file:/home/user/test.dat。

1.3.5 Web Application Conditions

  • @ConditionalOnWebApplication和@ConditionalOnNotWebApplication兩個註解會根據應用是否爲一個Web應用而使配置生效。

2. 一個自動配置的小例子

2.1 建立一個接受配置屬性的類

若是對於如何用java實體類進行接受配置文件的屬性不明白的,能夠參考個人文章不學無數——SpringBoot入門Ⅲ,裏面有詳細講解。

@ConfigurationProperties("acme")
@Validated
public class AcmeProperties {
	private boolean enabled;
	@NotNull(message = "不能weikong ")
	private String remoteAddress;

	public boolean isEnabled() { return enabled; }

	public void setEnabled(boolean enabled) { this.enabled=enabled; }

	public String getRemoteAddress() { return remoteAddress; }

	public void setRemoteAddress(String remoteAddress) { this.remoteAddress=remoteAddress; }

}

2.2 建立配置屬性的類

這裏只是簡單的舉個配置屬性的例子: 例如在這裏能夠進行配置數據庫的事務。而後在動態建立數據源的時候能夠判斷這個類是否建立而後建立數據源。

即這個類是一個做爲判斷依據的類

public class AcmeService {
    private String msg;

    public String getMsg() {
        return msg;
    }

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

    @Override
    public String toString() {
        return "AcmeService{" +
                "msg='" + msg + '\'' +
                '}';
    }
}

2.3 建立自動配置的類

@ConditionalOnClass該註解在以前已經講過,這裏的意思就是AcmeService類在路徑中已經存在之後纔會解析配置類。 @ConditionalOnMissingBean方法上的註解咱們上面也解釋過了,在這的意思就是在容器中沒有AcmeService對象時纔會實例化此Bean。

@Configuration
@ConditionalOnClass(AcmeService.class)
@EnableConfigurationProperties(AcmeProperties.class)
public class AcmeAutoConfiguration {

    private final AcmeProperties acmeProperties;

    public AcmeAutoConfiguration(AcmeProperties acmeProperties) {
        this.acmeProperties = acmeProperties;
    }

    @Bean
    @ConditionalOnMissingBean(AcmeService.class)
    public AcmeService getAcmeService(){
        AcmeService acmeService=new AcmeService();
        acmeService.setMsg(acmeProperties.toString());
        return acmeService;
    }
}

2.4 註冊配置

resources-META-INF文件夾下建立spring.factories文件,裏面寫入自動配置類的路徑

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.FirstSpringBoot.Configuration.AcmeAutoConfiguration

2.5 開始使用

由於咱們建立的自動配置是要供別人使用的,只對外提供配置的屬性值,因此咱們將咱們寫的自動配置的一系列類進行打jar包,另外一個項目引用事後只須要在配置文件中配置咱們對外提供的配置屬性進行配置之後就可使用咱們自動配置類提供的功能了。這也正符合了SpringBoot的開箱即用的觀點。

相關文章
相關標籤/搜索