从零开始学习SpringBoot

SpringBoot - SpringBoot配置文件

2018-05-07  本文已影响50人  BzCoder

SpringBoot最大的的优势就是简化了SpringMVC中很多繁琐的配置工作,采用了自动配置以及利用注解的方式代替原来的XML配置的方式来配置工程。

一.Bean的配置

配置JAVA注解 :@Configuration
Bean添加到容器的注解:@Bean

package com.springboot.config;

import com.springboot.service.HelloService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
 * @author BaoZhou
 * @date 2018/5/4
 */
@Configuration
public class MyAppConfig {
    //讲方法的返回值添加到容器中
    @Bean
    public HelloService helloservice() {
        System.out.println("配置类@bean给容器中添加组件");
        return new HelloService();
    }
}

二.多Profile配置

1.properties方式

我们在主配置文件编写的时候,文件名可以是application-{profile}.properites/yml,模式使用application.properties;选择某个profile时,只需要用如下代码:

spring.profiles.active=profile //此处为你定义的profile

2.YML方式

可以利用YML的文件块特性


server:
  port: 8081
spring:
  active: dev  //此处激活
---
server:
  port: 8083
spring:
  profiles: dev  
---
server:
  port: 8084
spring:
  profiles: prod

利用横线(---)进行文件块的划分,再需要激活的配置文件部分写上active,其他用profiles:命名即可

3.命令行

命令行方式

或者在打出JAR包后利用指令--spring.profile.active=dev运行JAR包

4.虚拟机参数

虚拟机参数

-Dspring.profiles.active=dev;

三.配置文件的加载路径

springboot会从以下路径去搜索配置文件,配置文件名字默认为application.properties/yml

路径由高到低:

file ../config
file ../
classpath:/confi/g
classpath:/

其中有相同属性时,优先级会覆盖低优先级。有不同属性时,配置文件之间会形成互补。

四.可配置的属性

参考SpringBoot官方文档

五.自动配置原理

通过注释@SpringBootApplication加载主配置类

方法继承关系:
SpringBootApplication注释
--> EnableAutoConfiguration注释
--> AutoConfigurationImportSelector.class类
--> getCandidateConfigurations方法
--> SpringFactoriesLoader方法
--> 从META-INF/spring.factories里读取配置参数键值对

读取配置参数代码如下

@Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        AutoConfigurationMetadata autoConfigurationMetadata =
        AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        List<String> configurations =
        getCandidateConfigurations(annotationMetadata,attributes);
        configurations = removeDuplicates(configurations);
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        configurations = filter(configurations, autoConfigurationMetadata);
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return StringUtils.toStringArray(configurations);
    }
    

首先读取JAR包中META-INF/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.CloudAutoConfiguration,\
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.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\
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,\

那么自动配置的组件是如何完成自动配置的呢,我们以HttpEncodingAutoConfiguration为例,上面的几个conditional都是用来判断配置是否生效。

@Configuration  //表示这是一个配置类
@EnableConfigurationProperties(HttpEncodingProperties.class)//启用configurationProperties功能,把HttpEncodingProperties加入到IOC容器中
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)//条件判断,满足条件配置类才能生效,判断当前应用是否为WEB引用
@ConditionalOnClass(CharacterEncodingFilter.class)//条件判断,判断当前项目是否有CharacterEncodingFilter.class类
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)//条件判断,判断配置文件是否存再spring.http.encoding,假如没有也返回为true
public class HttpEncodingAutoConfiguration {

EnableConfigurationProperties为配置属性,我们所能够配置的属性都在这个类中。读取配置文件取指定的值后再与Bean进行绑定。

@ConfigurationProperties(prefix = "spring.http.encoding")
public class HttpEncodingProperties {
    private final HttpEncodingProperties properties;
    //当只有一个有参构造时,他会从IOC容器中读取
    public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
        this.properties = properties;
    }
    @Bean
    @ConditionalOnMissingBean
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
        filter.setEncoding(this.properties.getCharset().name());
        filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
        return filter;
    }

自动配置原理小结

  1. SpringBoot启动时会加载大量的自动配置类。
  2. 我们看我们需要的功能是否有默认的自动配置。
  3. 查看自动配置类中配置了哪些组件。
  4. 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性,我们就可以在配置文件中设定这些属性的值。
    xxxxAutoConfiguration:自动配置类
    xxxxPropertios:封装配置文件中相关属性

六.有关于条件筛选@Conditional注释

SpringBoot再@Conditional又扩展出了多个注解以方面使用:

注解 作用 例子
@ConditionalOnJava 系统JAVA版本是否符合要求 ConditionalOnJava(JavaVersion.EIGHT)
@ConditionalOnBean
@ConditionalOnMissingBean
容器中(不)存在指定BEAN @ConditionalOnBean(javax.sql.DataSource.class)
@ConditionalOnExpression 满足SqEL表达式指定 @ConditionalOnExpression("'${server.host}'=='localhost'")
@ConditionaOnClass
@ConditionalOnMissingClass
容器中(不)存在指定Class @ConditionalOnClass({ test.class,test2.class })
@ConditionalOnSingleCandidate 容器中只有一个指定的Bean或者这个Bean是首选Bean @ConditionalOnSingleCandidate(test.class)
@ConditionalOnProperty 系统中指定的属性是否有指定的值 @ConditionalOnProperty(prefix = "spring.aop", name = "auto",matchIfMissing = true)
@ConditionalOnResource 类路径下是否有指定的资源文件 @ConditionalOnResource(resources="mybatis.xml")
@ConditionalOnWebApplication
@ConditionalOnNotWebApplication
当前(不)是WEB环境 无参数
@ConditionalOnjndi JNDI存在指定项 --

你可以在配置文件中添加

debug=true

在日志中查看在你的项目中启用了哪些自动配置类

那么有关于SpringBoot配置文件的相关学习笔记小结就到这里了。觉得不错的话可以点一个喜欢,谢谢大家!

上一篇下一篇

猜你喜欢

热点阅读