Spring Boot--yml/properties配置文件以及部分源码

我的博客: aaatao66.github.io/

开发环境:php

  • win10
  • jdk1.8
  • idea2019
  • maven 3.2.5
  • Spring Boot v2.1.5.RELEASE (版本)

1. yml文件的语法概览:

person:
 lastNAME: carson
 age: 18
 boss: true
 birth: 1234/12/12
  #map写法: {k: v,k2: v2}
 maps: {k1: v1,k2: v2}
  #数组写法: -值
 lists:
 - lisi
 - zhangsan
 - wangwu
 - zhaoliu
 dog:
 name: 小狗
 age: 3

spring:
 mvc:
 view:
 prefix: /WEB-INF/views/
 suffix: .jsp
 datasource:
 url: jdbc:mysql:///ssm
 username: root
 password: root
 driver-class-name: com.mysql.jdbc.Driver
 jpa:
 hibernate:
 ddl-auto: update

server:
 port: 9090
复制代码

2. @Value获取值和 @ConfigurationProperties获取值比较

@ConfigurationProperties @Value
批量注入配置文件中的属性 功能 一个个指定
支持 松散绑定(松散语法)大小写 不支持
不支持 SpEL表达式 支持
支持 JSR303数据校验 不支持
支持 复杂类型封装 不支持

这两种方式都能获取值:html

  • 若是,咱们只是在某个业务逻辑中须要获取一下配置文件中的某项值,使用@Value
  • 若是,咱们专门编写了一个javaBean来和配置文件进行映射;@ConfigurationProperties

@Validatedjava

@Valuemysql

@Getter@Setter
@ToString
@Component
//@ConfigurationProperties (prefix = "person")
@Validated // 来校验数据,若是数据异常则会统一抛出异常,方便异常中心统一处理。
public class Person {

    // @Email
    @Value("${person.lastNAME}")
    private String lastNAME;
    @Value("#{3*3}")
    private Integer age;
    private Boolean boss;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;

    private Dog dog;
}
复制代码

3. @PropertySource&@ImportResource

由于 @ConfigurationProperties 是全局注解,若是想指定的话git

  • @PropertySource:能够指定某个文件 @PropertySource("classpath: xxx.properties)

@ImportResource: 导入Spring配置文件,让配置文件里面的内容生效github

  • 建立一个HelloService 类
    • 若是没有注解状况下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="helloService" class="com.carson.springboot.service.impl.HelloService"></bean>
</beans>
复制代码
@Autowired
    ApplicationContext ioc;

    @Test
    public void testHelloService(){
        // 是不是包含 这个 bean
        boolean b = ioc.containsBean("helloService");
        System.out.println(b);//false
    }
复制代码

false 说明Spring Boot 里面没有Spring的配置文件,咱们本身编写的配置文件,也不能自动识别spring

若是想让Spring的配置文件生效,加载进来; 就 把@ImportResource标注在一个配置类上sql

  • 主类
@ImportResource(locations = {"classpath:beans.xml"})
@SpringBootApplication
public class SpringbootApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootApplication.class, args);
    }

}
复制代码
@Autowired
    ApplicationContext ioc;

    @Test
    public void testHelloService(){
        // 是不是包含 这个 bean
        boolean b = ioc.containsBean("helloService");
        System.out.println(b);//true
    }
复制代码

SpringBoot推荐给容器中添加组件的方式:数据库

使用 @Bean数组

  • 1, 配置类======Spring配置文件
    • 建一个包 config,专门放配置类:MyAppConfig
/** * @Configuration: 指明当前类是一个配置类;就是来代替以前的Spring配置文件 * * 之前配置文件总 用 <bean></bean> 标签添加组件 */
@Configuration
public class MyAppConfig {

    // 将方法的返回值添加到容器中,容器中这几个组件默认的id就是方法名
    @Bean
    public HelloService helloService(){
        return new HelloService();
    }
}
复制代码

记得把以前主类的@ImportResource注解 去掉!

输出结果:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.1.5.RELEASE) 2019-06-29 16:53:48.081 INFO 11084 --- [ main] c.c.s.SpringbootApplicationTests : Starting SpringbootApplicationTests on DESKTOP-JBSD6AK with PID 11084 (started by My in F:\code\springboot) 2019-06-29 16:53:48.083 INFO 11084 --- [ main] c.c.s.SpringbootApplicationTests : No active profile set, falling back to default profiles: default 2019-06-29 16:53:52.689 INFO 11084 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2019-06-29 16:53:53.988 INFO 11084 --- [ main] c.c.s.SpringbootApplicationTests : Started SpringbootApplicationTests in 7.259 seconds (JVM running for 10.759) true 2019-06-29 16:53:54.433 INFO 11084 --- [ Thread-3] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor' 复制代码

也是 true

4. 配置文件里的 ${}

random随机数

${random.value}
${random.int}
${random.long}
${random.int(10)}
${random.int[1024,65536]}
复制代码

${} 获取 以前配置的值

person:
 lastNAME: bob${random.uuid}
 age: ${random.int}
 boss: true
 birth: 1234/12/12
 maps: {k1: v1,k2: v2}
 lists:
 - lisi
 - zhangsan
 - wangwu
 - zhaoliu
 dog:
 name: ${person.lastNAME}_dog
 age: 3
复制代码

若是

 dog:
name: ${person.lastNAME}_dog
复制代码

若是lastNAME没有的话, 那就

 dog:
name: ${person.lastNAME:hello}_dog
复制代码

5. Profile

5.1 多个Profile 文件

Profile是Spring对不一样环境提供不一样配置功能的支持,能够经过指定参数等方式快速切换环境

好比我配置3个端口,一个默认的,一个dev(开发),一个prod(测试)

主配置文件名能够是 application.yml/application.properties

默认使用application.yml的配置;

5.2 yml的多文档块

以 --- 分隔 文档快

spring:
  profiles:
    active: dev 

server:
  port: 9090
---

server:
  port: 9091
spring:
  profiles: dev 
---

server:
  port: 9092
spring:
  profiles: prod
复制代码
  • active:是指定哪一个文档快
  • profiles: 指定一个名称,让active识别的

5.3 激活指定profile

1, 在配置文件中指定 spring.profiles.active=dev

2, 命令行:

idea功能栏中的 run > edit > program arguments 添加上

--spring.profiles.active=prod

--spring.profiles.active=dev

3,cmd中 将 项目打成 jar包

java -jar (jar包名) --spring.profiles.active=prod

4, 虚拟机 参数:

idea功能栏中的 run > edit >VM options 添加上

-Dspring.profiles.active=prod/dev


6.Spring Boot配置文件的加载位置

Spring Boot 启动会扫描如下位置的application.yml或application.properties文件做为默认配置文件

  • file: ./config/
  • file: ./
  • classpath: ./config/
  • classpath: /

以上是按照优先级从高到低的顺序,全部的配置文件都会被加载,高优先级配置会覆盖 低优先级配置

file : 跟src平级的目录

classpath: resources目录下的

咱们也能够经过配置spring.config.location来改变默认配置文件位置:

1.将项目打包

2.命令行格式: java -jar 包名 --spring.config.location= F:/app/application.properties(配置文件绝对路径)

项目打包以后可能后来会须要修改一些配置,就可使用这种方式,而且旧配置还会存在,新配置也会应用上

7.外部配置加载顺序

SpringBoot也能够从如下位置加载配置,优先级从高到低,高优先级覆盖低优先级,若是有不一样的配置,就会造成互补

  1. 命令行参数

    java -jar xxx.jar --server.port=8081 --xxx

    多个配置用空格分开: --xxx --xxx

  2. 来自java:comp/env的NDI属性

  3. Java系统属性(System.getProperties())

  4. 操做系统环境变量

  5. RandomValuePropertySource配置的random.*属性值

由jar包外向jar包内进行寻找:

优先加载带profile的

  1. jar包"外"部的application-{profile}.properties或application.yml(带spring.profile)的配置文件
  2. jar包''内''部的application-{profile}.properties或application.yml(带spring.profile)的配置文件

再来加载不带profile的

  1. jar包''外''部的application.properties或application.yml(不带spring.profile)的配置文件
  2. jar包''内''部的application.properties或application.yml(不带spring.profile)的配置文件

还有其余的:

  1. @Configuration注解类上的@PropertySource
  2. 经过SrpingApplication.setDefaultProperties指定默认属性

详情参考官网文档的第 24章

8.自动配置原理(重点)

自动配置到底能些什么?怎么写?自动配置原理:

文档地址

查看目录最后一章 X. Appendices

这里面说明了都有哪些配置项

其实:

  • 1.SpringBoot启动会加载大量的自动配置类
  • 2.咱们看咱们须要的功能有没有SpringBoot默认写好的自动配置类
  • 3.咱们再来看这个自动配置类到底配置了哪些组件(只要咱们要用的组件有,咱们就不须要再来配置了)
  • 4.给容器中自动配置类添加组建的时候,会从properties类中获取某些属性,咱们就能够在配置文件中指定这些属性的值

xxxxAutoConfigurartion: 自动配置类;

给容器中添加组件

xxxxProperties:封装配置文件中相关属性;

技巧:

idea双击Shift,搜索 *AutoConfiguration

点开缓存相关的自动配置

咱们将会看到如下源码:

@EnableConfigurationProperties({CacheProperties.class})
@AutoConfigureAfter({CouchbaseAutoConfiguration.class, HazelcastAutoConfiguration.class, HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class})
@Import({CacheAutoConfiguration.CacheConfigurationImportSelector.class})
public class CacheAutoConfiguration {
    public CacheAutoConfiguration() {
    }
复制代码

ctrl+鼠标左键点击:

@EnableConfigurationProperties({CacheProperties.class})
//点击 CacheProperties
复制代码

咱们会看到在CacheProperties类上:

@ConfigurationProperties(
    prefix = "spring.cache"
)
public class CacheProperties {
复制代码

prefix = "spring.cache" : 就是在yml/properties配置文件的语法前缀

至于能配置哪些具体东西?

就是这些

或者你能够利用idea的代码提示在配置文件里,好比我调用 第一个getType

这就是经过源码的方式,来了解到咱们能够在配置文件里配置什么东西

好比我想链接数据库,我来搜索一下

我看到了咱们的须要的字段,以及下面不少的方法(这里就不截图了)

接下来就是到配置文件配置了:

9.细节

@Conditional派生注解

我发现源码中有不少的 @ConditionalOn***

它其实就是利用Spring底层的 @Conditional注解

做用: 必须是 @Conditional 指定的条件成立,才给容器中添加组件,配置类里面的内容才会生效,若是返回false那么,你配的东西都不会生效的

SpringBoot 扩展了 @Conditional注解 好比:

因此其实自动配置类必须在必定的条件下才能生效

咱们该怎么知道哪些类生效哪些没生效呢?很简单,在配置文件里添加:

debug: true	
复制代码

而后运行咱们的朱类:

​ 咱们会看到:

还有:

都会在控制台打印输出
相关文章
相关标签/搜索