六、配置文件加载
SpringBoot 启动会扫描以下位置的application.properties或者application.yml文件作为SpringBoot的默认配置文件
- file:./config/
- file: ./
- classpath: /config/
- classpath: /
- 以上按照访问优先级从高到底的顺序,将所有位置的文件都会被加载,高优先级的配置会覆盖掉低优先级的内容
- 我们也可以通过配置spring.config.location来改变默认配置。
七、外部配置加载顺序
SpringBoot也可以从以下位置加载配置;优先级从高到低;高优先级的配置覆盖低优先级的配置,所有配置之间互补。
-
命令行参数
java -jar xxx.jar --server.servlet.context-path=/hello --server.port=8081
多个配置参数之间用空格分开 --配置项=值
需要注意的是在SpringBoot1.0-2.0时配置路径的参数是server.context-path; 现在都是2.0往上了所以需要改成server.servlet.context-path -
来自java:comp/env的JNDI属性
-
Java系统属性
-
操作系统环境变量
-
RandomValuePropertySource配置的random.*属性
-
jar包外部的application-profile.properties或application.yml 这些是带上spring.profile配置文件
-
jar包内部的application-profile.properties或application.yml 这些是带spring.profile配置文件
-
jar包外部的application-profile.properties或application.yml
-
jar包内部的application-profile.properties或application.yml
有jar包外的配置文件先加载外面的再加载里面的,如果是profile文件先加载带profile字段的配置文件 -
@Configuration注解类上的@PropertySource
-
通过SpringApplication.setDefaultProperties指定的默认属性
八、自动配置原理
自动配置原理:
SpringBoot启动时会加载主配置类,开启了自动配置功能@EnableAutoConfiguration
@EnableAutoConfiguration的作用:
- 利用AutoConfigurationImportSelector给IOC容器中导入一些组件
- 可以查看AutoConfigurationImportSelector类中selectImports方法
- 其中在getAutoConfigurationEntry方法中的
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
SpringFactoriesLoader.loadFactoryNames()
这个方法会扫描所有jar包类路径下META/spring.factories文件他把扫描到的这些文件的内容封装成properties对象,从properties中获取到EnableAutoConfiguration.class类对应的值然后把它添加到容器中
将类路径下META/spring.factories里面的所有EnableAutoConfiguration的值加入到了容器中;
也就是以下的内容
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration
每个自动配置类都会进行自动配置功能
以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理
@Configuration(
//表示是一个配置类,以前编写的配置文件一样,可以给容器中添加组件
proxyBeanMethods = false
)
@EnableConfigurationProperties({HttpProperties.class})
//启动HttpProperties属性类的ConfigurationProperties功能,将配置文件中对应的值和HttpEncodingProperties绑定起来
@ConditionalOnWebApplication(
//判断当前应用是否是Web应用,如果是,配置类才会起作用
type = Type.SERVLET
)
//ConditionalOnClass判断当前项目中是否含有CharacterEncodingFilter类;
//并把CharacterEncodingFilter类加载到IOC容器中。
@ConditionalOnClass({CharacterEncodingFilter.class})
@ConditionalOnProperty(
//判断当前项目中是否含有spring.http.encoding.enabled属性,
// matchIfMissing = true即使没有这个属性也会返回true,也是生效的
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
private final Encoding properties;
根据当前不同条件的判断,决定这个配置类是否生效?如果生效,这个配置类会与IOC容器中添加各种组件;这些组件的属性是从对应的properties类中获取的,而properties类里面的属性有事和SpringBoot配置文件中的属性绑定的。
重点:
- SpringBoot启动会加载大量的自动配置类
- 我们在SpringBoot默认写好的自动配置类中查看有没有与我们想要的功能的组件
- 如果有我们就不需要再配置了
- 如果没有我们可以在配置文件中指定这些属性的值,因为IOC容器添加组件的时候,会从properties类中获取某些属性,而xxxProperties类中的属性获取又是和我们写的配置文件中的属性绑定在一起的。
@Conditional派生注解
查看@Conditional注解的源码实现
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class<? extends Condition>[] value();
}
这玩意儿继承了Condition,Condition接口是Spring4中的条件接口,需要实现matches方法,返回值是boolean类型.
public interface Condition {
boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
我们查看SpringBootCondition这个抽象类的结构
public abstract class SpringBootCondition implements Condition {
private final Log logger = LogFactory.getLog(this.getClass());
public SpringBootCondition() {
}
public final boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String classOrMethodName = getClassOrMethodName(metadata);
try {
ConditionOutcome outcome = this.getMatchOutcome(context, metadata);
this.logOutcome(classOrMethodName, outcome);
this.recordEvaluation(context, classOrMethodName, outcome);
return outcome.isMatch();
} catch (NoClassDefFoundError var5) {
throw new IllegalStateException("Could not evaluate condition on " + classOrMethodName + " due to " + var5.getMessage() + " not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake)", var5);
} catch (RuntimeException var6) {
throw new IllegalStateException("Error processing condition on " + this.getName(metadata), var6);
}
}
原来下面的派生注解都是继承了SpringBootCondition,而SpringBootCondition又实现类Condition接口,重写了matches方法。
- @Conditional派生注解 作用(都是判断是否符合指定的条件)
- @ConditionalOnJava 系统的java版本是否符合要求
- @ConditionalOnBean 有指定的Bean类
- @ConditionalOnMissingBean 没有指定的bean类
- @ConditionalOnExpression 符合指定的SpEL表达式
- @ConditionalOnClass 有指定的类
- @ConditionalOnMissingClass 没有指定的类
- @ConditionalOnSingleCandidate 容器只有一个指定的bean,或者这个bean是首选bean
- @ConditionalOnProperty 指定的property属性有指定的值
- @ConditionalOnResource 路径下存在指定的资源
- @ConditionalOnWebApplication 系统环境是web环境
- @ConditionalOnNotWebApplication 系统环境不是web环境
- @ConditionalOnjndi JNDI存在指定的项
既然自动配置类必须在一定的条件下才能生效(也就是matches方法返回true)那么我们怎么知道到底哪些自动配置类生效,哪些没有生效?
解决方法:我们可以启用debug模式,让控制台打印哪些配置类生效哪些没有。
在application.yml/properties中设置 debug:true;/ debug=true(任意一处设置即可)
控制台输出内容:
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches://已经匹配的配置类
AopAutoConfiguration matched:
- @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)
…
Negative matches://没有生效的配置类
ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ‘javax.jms.ConnectionFactory’ (OnClassCondition)
这样我们就可以知道哪些配置类生效,哪些没有。
初学菜鸟,以上有不足之处敬请指出!