一、習慣優於配置
- spring-boot-autoconfigure-x.x.x.x.jar該jar囊括了大多數流行的第三方技術框架,已經給我們配置好了一套默認配置
- spring boot默認讀取application.properties配置文件
二、運行原理
- 核心註解@SpringBootApplication,而實際上它是有三個註解組成,分別是@Configuration、@EnableAutoConfiguration、@ComponentScan,而核心功能是由@EnableAutoConfiguration這個註解提供的
- 在@EnableAutoConfiguration註解裏的關鍵功能是@Import註解,導入的配置功能
EnableAutoConfigurationImportSelector使用SpringFactoriesLoader.loadFactoryNames方法來掃描具有META-INF/spring.factories文件的jar包,這個文件中聲明瞭有哪些要自動配置
三、分析mongodb的自動配置
- 打開org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration
package org.springframework.boot.autoconfigure.mongo;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import java.net.UnknownHostException;
import javax.annotation.PreDestroy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
@Configuration
@ConditionalOnClass({MongoClient.class})
@EnableConfigurationProperties({MongoProperties.class}) //開啓屬性注入。
@ConditionalOnMissingBean(
type = {"org.springframework.data.mongodb.MongoDbFactory"}
)
public class MongoAutoConfiguration {
@Autowired
private MongoProperties properties;
@Autowired(
required = false
)
private MongoClientOptions options;
@Autowired
private Environment environment;
private MongoClient mongo;
public MongoAutoConfiguration() {
}
@PreDestroy
public void close() {
if(this.mongo != null) {
this.mongo.close();
}
}
@Bean //使用java配置,當容器中沒有這個bean的時候執行初始化
@ConditionalOnMissingBean
public MongoClient mongo() throws UnknownHostException {
this.mongo = this.properties.createMongoClient(this.options, this.environment);
return this.mongo;
}
}
首先這被@Configuration註解了,是一個配置類,當滿足以下條件這個bean被裝配:
當MongoClient在類路徑下。
當容器中沒有org.springframework.data.mongodb.MongoDbFactory這類bean的時候。
此外,我們可以看一下通過@EnableConfigurationProperties({MongoProperties.class}) 自動注入的屬性(這是習慣優於配置的最終落地點):@ConfigurationProperties( prefix = "spring.data.mongodb" ) public class MongoProperties { public static final int DEFAULT_PORT = 27017; private String host; private Integer port = null; private String uri = "mongodb://localhost/test"; private String database; private String authenticationDatabase; private String gridFsDatabase; private String username; private char[] password; private Class<?> fieldNamingStrategy; ...... }
所以在我們什麼都不幹的情況下,只需要引入spring-data-mongodb這個依賴再加上默認的MongoDB server我們就能夠快速集成MongoDB,用MongodbTemplate訪問數據庫。
同時我們可以通過在application.properties中修改spring.data.mongodb相關的參數就能夠修改連接配置,如:spring.data.mongodb.host=localhost spring.data.mongodb.port=27017 spring.data.mongodb.username=poa spring.data.mongodb.password=poa spring.data.mongodb.database=test
四、製作自己的Starter
Spring Boot自動裝配
- Bean條件裝配
@ConditionalOnBean:當容器裏有指定的bean的條件下。
@ConditionalOnMissingBean:當容器裏不存在指定bean的條件下。- Bean條件裝配
- Class條件裝配
@ConditionalOnClass:當類路徑下有指定類的條件下。
@ConditionalOnMissingClass:當類路徑下不存在指定類的條件下。 - Environment裝配
@ConditionalOnProperty:指定的屬性是否有指定的值,比如@ConditionalOnProperties(prefix=”xxx.xxx”, value=”enable”, matchIfMissing=true),代表當xxx.xxx爲enable時條件的布爾值爲true,如果沒有設置的情況下也爲true。 - 其它裝配
@ConditionalOnExpression:當表達式爲true時,纔會實例化一個Bean。支持SpEL表達式。 @ConditionalOnJava:當存在制定Java版本的時候 - 聯合多條件
- 自定義條件(實現Condition接口)
其實編寫Starter與編寫一個普通的Spring Boot應用沒有太大區別,只要在pom文件中寫好依賴,使用@Configuration和@Bean來自動裝配集成。唯一的一點區別是需要告訴Spring Boot自動裝配類在哪裏,這是通過spring.factories文件完成的
@ConditionalOnClass : classpath中存在該類時起效
@ConditionalOnMissingClass : classpath中不存在該類時起效
@ConditionalOnBean : DI容器中存在該類型Bean時起效
@ConditionalOnMissingBean : DI容器中不存在該類型Bean時起效
@ConditionalOnSingleCandidate : DI容器中該類型Bean只有一個或@Primary的只有一個時起效
@ConditionalOnExpression : SpEL表達式結果爲true時
@ConditionalOnProperty : 參數設置或者值一致時起效
@ConditionalOnResource : 指定的文件存在時起效
@ConditionalOnJndi : 指定的JNDI存在時起效
@ConditionalOnJava : 指定的Java版本存在時起效
@ConditionalOnWebApplication : Web應用環境下起效
@ConditionalOnNotWebApplication : 非Web應用環境下起效
@AutoConfigureAfter:在指定的配置類初始化後再加載
@AutoConfigureBefore:在指定的配置類初始化前加載
@AutoConfigureOrder:數越小越先初始化