一、习惯优于配置
- 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:数越小越先初始化