SpringBoot02

使用Spring Initializer快速创建SpringBoot项目

SpringBoot02

SpringBoot02

SpringBoot02

  • 选好模块后, idea会联网帮我们导入相应的依赖.
  1. 这样主程序就生成好了, 只需要我们编写自己的逻辑即可.
  2. resources文件夹中目录结构

SpringBoot02

    1. static: 保存所有的静态资源; js, css, image.
    2. templates: 保存所有的模板页面
      • SpringBoot默认jar包使用嵌入式的Tomcat, 不支持jsp, 但可以使用模板引擎thymeleaf.
    3. application.properties: SpringBoot应用的配置文件, 可以修改一些默认设置.

SpringBoot配置

配置文件

  1. SpringBoot使用一个全局的配置文件
    1. application.properties
    2. 或application.yml
  2. 配置文件的作用: 修改SpringBoot自动配置的默认值.
  3. 配置文件放在src/main/resources目录下.

YAML语法

  1. 以前我们的配置文件大多是xml文件, 而yml是以数据为中心的, 比起xml, json更适合做配置文件
    server:
        port: 8081
  2. 基本语法
    1. k: v 表示一对键值对(冒号后必须有空格)
    2. 以空格的缩进控制层级关系: 左对齐的一列数据都是同一层级的.
      server: 
          port: 8080
          path: /hello
    3. 属性和值大小写敏感.
  3. 值的写法
    1. 字面量: 普通值(数字,字符串,布尔)
      • k: v 字面量直接来写, 字符串默认不用加引号.
      • "xxx": 双引号不会转义字符串中的特殊字符.
      • 'xxx': 单引号会转义字符串中的特殊字符(特殊字符最终只是一个普通字符串输出)
    2. 对象: Map(键值对) 在下一行来写对象的属性和值的关系
      • 对象还是k: v的形式
        friends: 
            lastName: zhangsan
            age: 20
      • 行内写法
        friends: {lastName: zhangsan, age: 18}
    3. 数组(List, Set)
      • 用 - 表示数组中的一个元素
        pets:
         - cat
         - dog
         - pig
      • 行内写法
        pets: [cat, dog, pig]

配置文件的注入

  1. yml配置文件
    server: 
        port: 8081
    
    person: 
        lastName: zhangsan
        age: 18
        boss: false
        birth: 2020/5/11
        map: {k1: v1, k2: v2}
        list: 
         - lisi
         - zhaoliu
        dog:
            name: 小狗
            age: 2
  2. 实体类
    /**
     * 将配置文件中每个属性的值映射到这个组件中
     * @ConfigurationProperties: 告诉SpringBoot将本类中所有属性和配置文件中的相关配置绑定
     *  prefix = "person": 与配置文件中哪个属性的下面一一对应.
     * 只有这个组件是容器的组件, 才能提供@ConfigurationProperties的功能.
     */
    @Component
    @ConfigurationProperties(prefix = "person")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Person {
    
        private String lastName;
        private Integer age;
        private Boolean boss;
        private Date birth;
    
        private Map<String, Object> map;
        private List<Object> list;
        private Dog dog;
    }
  3. 再pom.xml中导入配置文件处理器, 这样以后写yml时就有提示了
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-configuration-processor</artifactId>
       <optional>true</optional>
    </dependency>
  4. 测试程序
    /**
     * SpringBoot单元测试
     * 可以在测试期间类似编码一样进行自动注入等容器功能
     */
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class SpringBoot02ConfigApplicationTests {
    
        @Autowired
        Person person;
    
        @Test
        public void contextLoads() {
            
            System.out.println(person);
        }
    }
  5. properties配置文件注入的写法
    person.last-name=张三
    person.age=18
    person.birth=2017/12/15
    person.boss=false
    person.map.k1=v1
    person.map.k2=14
    person.list=a,b,c
    person.dog.name=dog
    person.dog.age=15
    1. 倘若出现了中文的乱码问题

SpringBoot02

配置文件注入时的对比

  1. @Value获取值和@ConfigurationProperties获取值比较
    1. @ConfigurationProperties: 批量注入配置文件中的属性
      • 支持松散绑定语法
      • 不支持SpEL表达式
      • 支持JSR303数据校验
      • 支持复杂类型的封装
    2. @Value: 一个一个指定注入
      • 不支持松散绑定语法
      • 支持SpeL表达式
      • 不支持JSR303数据校验
      • 不支持复杂类型的封装
  2. 松散绑定
    1. 如 lastName 和 last-name 和 last_name 同义
  3. SpEL表达式
    /**
         * <bean class="Person">
         *      <property name="lastName" value="${SpeL}"></property>
         * </bean>
         */
         ${}内是表达式的值, 可以放在配置文件中.
        @Value("${person.last-name}")
        private String lastName;
  4. JSR303数据校验: 类上带 @Validated
    @Component
    @ConfigurationProperties(prefix = "person")
    @Validated
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Person {
    
        @Email
        private String lastName;
        private Integer age;
    }
    • 这样lastName必须为email格式的数据, 否则将报错.
  5. 总结
    1. 如果我们只是在某个业务逻辑中获取下配置文件中的某项值, 使用@Value, 如
      @RestController
      public class HelloController {
      
          @Value("${person.last-name}")
          private String name;
      
          @RequestMapping("/sayHello")
          public String sayHello() {
      
              return "Hello " + name;
          }
      }
    2. 如果我们专门编写javaBean来和配置文件进行映射, 则用@ConfigurationProperties

@PropertySource和@ImportSource

  1. @PropertySource: 加载指定的配置文件(不写的话会加载全局配置文件)
    1. value属性: 指定要加载的配置文件的位置
      @Component
      @PropertySource(value = "classpath:person.properties")
      @ConfigurationProperties(prefix = "person")
      @Data
      @NoArgsConstructor
      @AllArgsConstructor
      public class Person {
      
          private Integer age;
          private Boolean boss;
          private Date birth;
      
          private Map<String, Object> map;
          private List<Object> list;
          private Dog dog;
      }
  2. @ImportResource: 导入Spring的配置文件, 让配置文件中的内容生效.
    1. SpringBoot里边没有Spring的配置文件(xxx.xml), 我们自己编写, 也不能自动识别; 想让Spring的配置文件生效, 就需要把@ImportResource标注在配置类上
      @ImportResource(locations = {"classpath:beans.xml"})
      @SpringBootApplication
      public class MainType {
      
          public static void main(String[] args) {
              SpringApplication.run(MainType.class, args);
          }
      }
    2. 编写beans.xml
      <?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="top.binwenhome.service.HelloService"></bean>
      
      </beans>
  3. SpringBoot推荐给容器添加组件的方式: 使用全注解的方式
    1. 不用加@ImportResource了
    2. 配置类@Configuration
    3. 使用@Bean给容器中添加组件
      /**
       * 指明这是一个配置类, 来替代Spring的配置文件
       */
      @Configuration
      public class MyAppConfig {
      
          /**
           * 将方法的返回值添加到容器中, 容器中这个组件默认id是方法名
           */
          @Bean
          public HelloService helloService() {
              System.out.println("添加组件了");
              return new HelloService();
          }
      }
    4. 测试程序
      @RunWith(SpringRunner.class)
      @SpringBootTest
      public class SpringBoot02ConfigApplicationTests {
      
          @Autowired
          ApplicationContext ioc;
      
          @Test
          public void test() {
              boolean b = ioc.containsBean("helloService");
              System.out.println(b);
          }
      }

配置文件占位符

  1. 随机数
    ${random.value}, ${random.int}, ${random.long}
    ${random.int(10)}, ${random.int[100,1000]}
  2. 属性配置占位符
    1. 可以在配置文件中引用前面配置过的属性.
    2. 可以引用随机数
    3. ${xxx.xxx: 指定默认值}
      person.last‐name=张三${random.uuid} 
      person.age=${random.int} 
      person.birth=2017/12/15 
      person.boss=false 
      person.maps.k1=v1 
      person.maps.k2=14 
      person.lists=a,b,c 
      person.dog.name=${person.hello:hello}_dog 
      person.dog.age=15

 Profile

  1. Profile是Spring对不同环境提供不同配置功能的支持, 可以通过激活指定参数等方式快速切换环境.
  2. 多profile文件形式   
    1. 文件名格式: application-{profile}.properties/yml
      #application.properties
      server.port=8080
      spring.profiles.active=dev #指定要用的环境

      ==================分界线===================
      #application-dev.properties
      server.port=8081
      
      ==================分界线===================
      
      #application-product.properties
      server.port=8082
  3. yml支持多文档块方式
    server:
        port: 8081
    spring:
        profiles:
            active: prod   #指定用哪个环境
    
    ---
    
    server:
        port: 8082
    spring:
        profiles: dev
    
    ---
    
    server:
        port: 8084
    spring:
        profiles: product
  4. 激活指定profile
    1. 在配置文件中指定: spring.profiles.active=dev
    2. 命令行方式: --spring.profiles.active=dev
      1. SpringBoot02
    3. 虚拟机参数: -Dspring.profiles.active=dev
      1. SpringBoot02

 

配置文件加载位置

  1. springboot启动后会扫描以下位置的application.properties/yml文件作为springboot的默认配置文件. 
    1. -file: ./config/
    2. -file: ./
    3. -classpath: /config/
    4. -classpath: /
    5. 优先级从高到低, 高优先级的配置会覆盖低优先级的配置, 并且是互补配置.
      1. SpringBoot02
  2. 另外, 我们可以通过spring.config.location来改变默认的配置文件位置
    1. 项目打包好以后, 我们可以使用命令行参数的形式, 启动项目时来指定配置文件新位置, 同样是互补配置.
      java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --spring.config.location=D:/application.properties

外部配置的加载顺序

  1. springboot也可以从以下位置加载配置: 优先级从高到低, 高优先级覆盖低优先级, 互补配置.
    1. 命令行参数.
      • 所有的配置都可以在命令行上进行指定
        java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc 
      • 多个配置用空格分开; --配置项=值
      • 当然, 这样写比较复杂, 我们可以通过命令行的方式访问外部配置文件.
    2. jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件.
    3. jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件 
    4. jar包外部的application.properties或application.yml(不带spring.profile)配置文件
    5. jar包内部的application.properties或application.yml(不带spring.profile)配置文件
  2. 当然, 实际上有17种加载来源, 其他的用的不多
上一篇:Springboot02-IoC


下一篇:Nginx内置变量以及日志格式变量参数详解