SpringBoot的配置文件和自动配置原理

1、SpringBoot配置

1.1、使用Spring Initializer快速创建SpringBoot项目

可以使用IDEA的Spring Initializer快速创建项目,IDEA都支持使用Spring的项目创建一个SpringBoot项目,选择我们需要的模块;向导会联网创建一个SpringBoot项目。
默认生成的SpringBoot项目:
主程序已经生成好了,我们只需要添加我们自己的逻辑
resources文件夹中的目录结构

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

如下所示:

在这里插入图片描述

1.2、使用Maven创建一个继承式的SpringBoot项目

1.2.1、创建父模块

1、使用idea新建一个项目,出现下面界面,选择Spring Initializer并点击next

在这里插入图片描述

2、填写一些创建项目所需的属性值(请注意父级Maven项目的注意点),然后点击next

在这里插入图片描述

3、可以选择一些start场景,比如创建web应用需要选择web等等,在这里我们是创建一个父级项目,所以我们需要选择以下SpringBoot的版本号,选择最稳定的那个。后面带(SNAPSHOT),代表版本开发中,不稳定。然后点击next。

在这里插入图片描述

1.2.2、创建子模块

1、使用idea新建一个项目,出现下面界面,选择Spring Initializer并点击next

在这里插入图片描述

2、填写对应的属性

在这里插入图片描述

3、在这里我们可以选择web应用和稳定版本,然后点击next构建子项目

在这里插入图片描述

4、修改子项目的pom文件中的配置,将父级改为我们自己创建的springboot_parent项目

在这里插入图片描述

5、如果打包报以下错误

 must be "pom" but is "jar" 

在父级的pom文件加入它

在这里插入图片描述

如果打包报错

Could not transfer artifact cool.ale:springboot_parent:pom:0.0.1-SNAPSHOT from/to nexus-releases (http://nexus-releases): nexus-releases

则去掉父级的相对路径或者写一个正确的:

在这里插入图片描述

1.3、自定义SpringApplication类

当自定义的时候,可以去操作SpringApplication类的一些方法,例如关闭启动时的横幅(图案)等。

package cool.ale;

import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringInitializerApplication {

    public static void main(String[] args) {
        SpringApplication springApplication =  new SpringApplication(SpringInitializerApplication.class);
        // 关闭横幅
        springApplication.setBannerMode(Banner.Mode.OFF);
        springApplication.run(args);
    }

}

1.4、application.yml配置文件简单介绍

和properties的区别是,它有严格的格式,类似于python一样,用空格区分
yml文件格式

server:
  port: 8082

properties文件格式

server.port=8088

1.5、application配置文件的加载顺序

1、application.yml
2、application.yaml
3、application.properties
SpringBoot会以上面的顺序进行加载,上面的1,2,3代表优先级,但是三者又存在互补的关系,就是如果application.yml里面没有的配置,但application.yaml里面有,application.yaml里面的配置就生效了。

1.6、其它配置的文件的加载顺序

1、jar包之外的配置文件,跟jar包同一级的。
2、制定了参数(spring.profiles.active),会去找相应的配置文件。
3、直接指定文件路径spring.config.location=D:\config/,这种方式不会和默认的约定的配置文件进行互补。
接下类我再细粒度的讲解一下
以下配置的优先级由低到高:
1、classpath路径下的:也就是resource路径下文件,当我们的resource路径下的文件编译过之后,就会放在classes目录下。

在这里插入图片描述

2、classpath路径下的config文件夹下:这里的优先级比1中的高一些。

在这里插入图片描述

3、项目的根目录下:如果项目是继承关系,那么根目录则以父级项目的根目录为主。

在这里插入图片描述

4、项目的根目录下的config文件夹下:

在这里插入图片描述

5、直接子目录:意思就是在使用java -jar命令启动时直接写在后面的参数的,示例下面两种,可以指定参数,也可以指定一个application的配置文件路径

java -jar .\springboot_helloworld-1.0-SNAPSHOT.jar --server.port=8090

第二种方式,在目录的最后一定要打上“/”

java -jar .\springboot_helloworld-1.0-SNAPSHOT.jar --spring.config.location=D:\config/

1.7、profile配置文件的加载

如果我们的配置文件有好几个类似于下面这个样子,首先肯定会加载application.yml文件。

在这里插入图片描述

但是如果我们在application.yml文件中设置了如下属性

spring:
  profiles:
    active: dev

则会加载application-dev.yml。
我们也可以放在类上,表示这个bean对象在什么时候起作用,@Profile(“prod”)属性和上面的属性(spring.profiles.active)相对应

@Profile("prod")
@RestController
@RequestMapping("/hello")
public class HelloController {
    public HelloController() {
        System.out.println("加载");
    }

    @RequestMapping("/init")
    public String sayHi(){
        return "Hello SpringBoot";
    }
}

1.8、多个配置文件存放

在SpringBoot中我们可以将不同的配置文件放在不同的文件夹下,这样我们就可以很好的区分这些配置文件,也避免了一个配置文件配置的参数过多,SpringBoot是支持通配符的,config/*/,所以我们可以这样做:

在这里插入图片描述

1.9、SpringBoot外部配置文件的读取优先级

由低到高

1、在启动配置类上加注解指向需要加载的配置文件,这里加载appSource.properties文件,比resources文件夹下的application.properties配置文件的优先级低,但是两者之间形成互补。一定要指定properties文件,yml文件是不可以的。

package cool.ale.springboot_initializer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.PropertySource;

@SpringBootApplication
@PropertySource("appSource.properties")
public class SpringbootInitializerApplication {

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

}

2、使用SpringApplication对象来设置配置文件,这里加载app.properties文件,比resources文件夹下的application.properties配置文件的优先级低,但是两者之间形成互补。

package cool.ale.springboot_extern_configuration;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * @author dujlc
 */
@SpringBootApplication
public class SpringbootExternConfigurationApplication {

    public static void main(String[] args) throws IOException {
        SpringApplication springApplication = new SpringApplication(SpringbootExternConfigurationApplication.class);
        // 创建properties
        Properties properties = new Properties();
        // 通过当前类的 ClassLoader 获得某一个资源转换为数据流(ResourceAsStream)
        InputStream is = SpringbootExternConfigurationApplication.class.getClassLoader().
                getResourceAsStream("app.properties");
        // 将输入流读取成 properties
        properties.load(is);
        // 设置一个资源文件在启动的时候去加载
        springApplication.setDefaultProperties(properties);
        springApplication.run(args);
    }

}

3、约定的配置文件,可参考5、6、7、8这几个一级标题
4、配置环境变量
4.1、配置idea的环境变量,属性不会互补
spring.config.location=D:\config/

在这里插入图片描述

4.2、配置windows的环境变量,属性不会互补
spring.config.location=D:\config/

在这里插入图片描述

清除刚才设置的环境变量,set后面什么值都不给就清除掉了

set spring.config.location=

4.3、以Java Vm参数的形式去执行配置文件
-Dspring.config.location=D:\config\appVm.properties

在这里插入图片描述

4.4、使用java命令行的方式
java -Dspring.config.location=D:\config\appVm.properties -jar 项目名

在这里插入图片描述

5、命令行参数,会使约定的配置失效

java -jar .\springboot_helloworld-1.0-SNAPSHOT.jar --spring.config.location=D:\config/

6、注释在测试类中的注解指定配置文件
@TestPropertySource(“classpath:appSource.properties”)

package cool.ale.springboot_extern_configuration;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

@SpringBootTest
@TestPropertySource("classpath:appSource.properties")
class SpringbootExternConfigurationApplicationTests {

    @Value("${server.port}")
    private String port;

    @Test
    void contextLoads() {
        System.out.println(port);
    }

}

2、SpringBoot自动配置原理

SpringBoot默认给了我们许多的整合框架,就比如当我们只需要在pom文件中引入spring-boot-starter-web,SpringBoot就会默认的给我们整合tomcat服务器,以及整合SpringMvc的东西,但是相对于一些往外发布的服务的端口之类的我们是可以在配置文件(application.yml)中修改的,所以就涉及到了大量的参数配置,当然,网上也有很多清单可供我们参考,但是也可以通过源码的方式来了解底层的配置,可快速找到一个相应的参数配置形式。

2.1、@SpringBootApplication注解依赖简介

依赖注解

@Target({ElementType.TYPE}) :设置当前注解可以标记在哪,TYPE是类,METHOD是方法等。
@Retention(RetentionPolicy.RUNTIME):编译后以什么方式保留,SOURCE只保留class文件,不保留注解,CLASS会保留注解,但不是加载到JVM中,RUNTIME会保留到文件,也会再加到JVM中。
@Documented :当我们使用Java Doc命令时,会生成注解信息。
@SpringBootConfiguration:进入里面会有注解@Configuration,标记成为一个注解类。
@EnableAutoConfiguration:开启SpringBoot的自动配置。
@ComponentScan:
1、扫描包,相当于之前在Spring.xml中写的<context:component-scan注解,这里面没有指定base-package属性,但是制定了一个自定义的排除方法Filter(type = FilterType.CUSTOM,classes = {TypeExcludeFilter.class},CUSTOM属性就是自定义,如果我们需要排除,我们需要写一个自定义类继承TypeExcludeFilter,并重写里面的match方法即可。
2、@Filter(type = FilterType.CUSTOM,classes ={AutoConfigurationExcludeFilter.class},排除所有配置类并且是自动配置类中的其中一个。

2.2、@EnableAutoConfiguration

进到SpringBoot的自动配置注解里,我们会发现它引入了以下几个注解
@AutoConfigurationPackage:将当前配置类所在的包保存在BasePackage的Bean中,供Spring内部使用。
@Import({AutoConfigurationImportSelector.class}):导入了一个AutoConfigurationImportSelector类,这个类实现了DeferredImportSelector接口,这个接口是一个变种的ImportSelector接口,他会比ImportSelector延迟去注入,返回一个类的完整限定名的数组。

2.3、SpringBoot自动配置类的流程

在这里插入图片描述
上面图的放大。

在这里插入图片描述

3、HttpEncodingAutoConfiguration示例

@Configuration(proxyBeanMethods = false):标记了@Configuration Spring底层会给配置创建cglib动态代理,设置为false,表示不代理,就是每一次调用的时候都会新new一个。
@EnableConfigurationProperties({ServerProperties.class}):启用可以在配置类设置的属性,对应的类。
@Conditional:它有很多子注解,可以约束某些类是否生效的条件。
@ConditionalOnWebApplication(type = Type.SERVLET):当在SERVLET的环境下,这个web环境才会起作用。
@ConditionalOnClass({CharacterEncodingFilter.class}):当前的jar包当中必须包含CharacterEncodingFilter类,才会起作用。
@@ConditionalOnProperty(prefix = “server.servlet.encoding”,value = {“enabled”},matchIfMissing = true):当server.servlet.encoding.enabled = true时,这个配置类才会起作用。

4、其他知识

4.1、如何看现在的项目启动了哪些自动配置类

在application.yml文件中写入属性:

debug=true

在控制台中Positive matches:就是已匹配的,Negative matches:就是未匹配的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值