我们并不是没有梦想,更不是没有努力过,而是未曾坚持下去!       

yml文件配置sql server_spring boot


SpringBoot

Spring Boot是Spring项目中的一个子工程,与我们所熟知的Spring-framework 同属于spring的产品(Spring家族中的一员)

springboot设计目的: 用来简化 Spring 应用的初始搭建以及开发过程

1、springboot主要特点

自动配置:不需要再关注各个框架的整合配置,springboot全部已经配置好了

起步依赖:我们在需要使用某个框架的时候, 直接添加这个框架的启动器依赖即可 , 不需要在关注jar包的冲突和整合

 启动器依赖(starter):就是springboot提前封装的项目模块


2、SpringBoot、 SpringMVC和Spring有什么区别

Spring是一个IOC容器,用来管理Bean,使用依赖注入实现控制反转,可以很方便的整合各种框架,提供AOP机制弥补OOP的代码重复问题、更方便将不同类不同方法中的共同处理抽取成切面、自动注入给方法执行,比如日志、异常等

OOP:面向对象程序设计

SpringMVC是Spring对web框架的一个解决方案,提供了一个DispatcherServlet,用来接收请求,然后定义了一套路由策略(url到handle的映射)及适配执行handle,将handle结果使用视图解析技术生成视图展现给前端

SpringBoot是Spring提供的一个快速开发工具包,让程序员能更方便、更快速的开发spring+springmvc应用,简化了配置(约定了默认配置),整合了一系列的解决方案(starter机制)、redis.mongodb.es,可以开箱即用


3、SpringBoot 优势

spring boot 其实不是什么新的框架,它默认配置了很多框架的使用方式,就像 maven 整合了所有的 jar 包,spring boot 整合了所有的框架

1.快速构建项目

2.零配置,遵循“约定大于配置”   编码<配置<约定

3.集成第三方库变为启动器,做到“开销即用”

4.嵌入tomcat服务器

使用Spring Boot开发时, 不需要关注各种复杂的整合配置 , 也不用关注各个库之间的依赖及冲突问题 , Spring Boot已经默认帮我们整合配置好了 !

节省了大量的配置及依赖调整时间, 让我们能够把时间用在刀刃上, 专注业务逻辑的开发。


4、SpringBoot 左下角启动项目配置

  • 正常情况按下图打开view下的tool windows会有一个services的选项,但是这里没有

1.点击Run,找到 Edit  Configurations

yml文件配置sql server_java_02


2.点击Templates(不用展开),展开右侧Configurations available services,点击加号

yml文件配置sql server_spring_03

3.点击加号,选择Spring Boot 确认后,效果如下

yml文件配置sql server_spring_04

4.效果,左下角出现services

yml文件配置sql server_配置文件_05


SpringBoot入门案例

该入门案例的需求很简单,如下。。

yml文件配置sql server_yml文件配置sql server_06

1、创建maven工程

如下图创建名为springboot_01的maven工程

注意下图中springboot_01和springboot是没有父子工程关系的; springboot的存在完全是为了方便管理各个模块,它可以没有

yml文件配置sql server_yml文件配置sql server_07


2、pom.xml中添加启动器

SpringBoot可以帮我们方便的管理项目依赖 , 在Spring Boot提供了一个名为**spring-boot-starter-parent**的工程,里面已经对各种常用依赖的版本进行了管理。

我们的项目需要以这个项目为父工程,这样我们就不用操心依赖的版本问题了,需要什么依赖,直接引入坐标(不需要添加版本)即可

在springboot_01工程的pom文件中:

添加父工程启动器 spring-boot-starter-parent

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.6.RELEASE</version> </parent>

添加web启动器:spring-boot-starter-web

为了让Spring Boot帮我们完成各种自动配置,我们必须引入Spring Boot提供的自动配置依赖,我们称为启动器。因为我们是web项目,这里我们引入web启动器

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>

这个启动器的依赖,它已经把自己运行所需要的必要包集成在这个启动器中,通过Maven的依赖传递性,将这些包都依赖到咱们的项目里了


3、创建启动类 Application

Spring Boot项目通过main函数即可启动,我们需要创建一个启动类

启动类可以1.启动tomcat   2.管理各种bean对象(扫描包)

springboot默认就是jar包,因为tomcat内置了

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

启动类的位置:要以上帝视角。默认扫描启动类所在包及子包下的类身上的注解

yml文件配置sql server_java_08


4、编写HelloController控制器

里面写一个控制器方法,处理/hello请求

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String sayHello(){
        return "hello spring boot!!" ;
    }
}

启动springboot项目,如下图:

yml文件配置sql server_yml文件配置sql server_09

在浏览器测试,成功搭建springboot-web项目

yml文件配置sql server_配置文件_10


5、使用Spring Initializr 快速创建

Spring Initializr 从本质上来说就是一个Web应用程序,它能为你生成Spring Boot项目结构。虽然不能生成应用程序代码,但它能为你提供一个基本的项目结构。

记得要改这里的配置URL    https://start.springboot.io 

yml文件配置sql server_spring_11


6、启动参数(VM Options)传入配置项

SpringBoot 既可以加载指定目录下的配置文件获取配置项,也可以通过启动参数(VM Options)传入配置项,注意:通过启动参数传入的配置项会“顶掉”配置文件中的配置

在上文中,我们的项目启动端口是8080,现在做如下操作

-Dserver.port=5555

yml文件配置sql server_配置文件_12


重新启动项目

yml文件配置sql server_配置文件_13

yml文件配置sql server_spring boot_14

IDEA 快捷键:

进入方法:  Ctrl + 鼠标左键

光标前进/后退: Ctrl + Shirt + 右方向键/左方向键


SpringBoot配置文件

配置文件必须放置在项目的类加载目录下, 并且名字必须是application

springboot项目在运行的时候会自动加载这些配置文件。名字必须是application.yaml,或

application.properties。选其一

1、properties文件

配置数据库连接信息,会重复去写“spring.jdbc.datasource”(这是properties文件的缺点)

spring.jdbc.datasource.driverClassName=com.mysql.jdbc.driver spring.jdbc.datasource.url=jdbc:mysql://springboot_01 spring.jdbc.datasource.username=xiaoyumao spring.jdbc.datasource.password=123456

根据配置文件中的属性,创建属性类DataSourceProperties,封装4个属性

@Value是spring中的注解,不是springboot的

import org.springframework.beans.factory.annotation.Value; @Component public class DataSourceProperties { @Value("${spring.jdbc.datasource.driverClassName}") private String driverClassName; @Value("${spring.jdbc.datasource.url}") private String url; @Value("${spring.jdbc.datasource.username}") private String username; @Value("${spring.jdbc.datasource.password}") private String password; //省略get/set方法/toString方法 }

在HelloController中,额外加入以下内容

yml文件配置sql server_配置文件_15


浏览器重新发起请求 http://localhost:8080/hello

查看控制台打印输出:

yml文件配置sql server_yml文件配置sql server_16


2、@Value

@Value("${server.port:8080}")
private int serverPort;

如上,如果在配置文件没有配置对应的属性,则使用8080作为默认值

给参数注入,执行set方法

public static String zhifuUrl;   
@Value("${zhifu.url}")  
public void setZhifuUrl(String url) {  
CrmUtil.zhifuUrl = url;  
}

注:在没有指定默认值的情况下,如果忘记在配置文件配置对应的属性,在程序启动时会报错,导致程序启动失败,这种情况可以为@Value指定默认值,来避免该问题


3、yaml 配置文件

当俩种格式(application.yaml,或application.properties)的配置文件都存在,读的是properties格式的配置文件。

yaml语法 :

1.数据结构用树形结构呈现,通过缩进来表示层级,

2.连续的项目(集合)通过减号 ” - ” 来表示

3.键值结构里面的key/value对用冒号 ” : ” 来分隔。

4.YAML配置文件的扩展名是yaml 或 yml

server: port: 8080 servlet: context-path: /demo

server.port  配置启动项目的tomact端口号

server.servlet.context-path 配置应用的上下文路径,也可以称为项目路径

  • server.servlet.context-path不配置时,默认为 / ,如:localhost:8080/xxxxxx
  • 当server.servlet.context-path有配置时,比如 /demo,此时的访问方式为localhost:8080/demo/xxxxxx

把上面说的properties属性文件,用yml的语法写就是如下:

spring:
  jdbc:
   datasource:
    driverClassName: com.mysql.jdbc.driver
    url: jdbc:mysql://springboot_01
    username: xiaoyumao
    password: 123456

上面这种数据源的连接方式是我们自定义的,以后数据源配置并不会这么使用

以后怎么连接数据库,使用下图框住的上面那个框下面那个框是自定义的,需要自己写配置类读取。上面的是springboot定义好的,直接可以用。

yml文件配置sql server_yml文件配置sql server_17


4、多环境profile切换配置

 [profile-配置文件]

场景:开发环境、测试环境、准生产环境、生产环境,每一个环境都有自己的数据库(需要通过yml配置)

Spring Boot项目中配置文件的名称只能是**application** , 如果我们把所有的配置全都写在一个配置文件中如果配置项比较多, 配置文件就会显得比较复杂和臃肿 ! 不利于后期的项目维护和开发

springboot中可以使用多个yaml配置文件,这些文件名称必须为application-***.yml,并且在application.yml中激活(文件中引用)

怎么快速灵活的切换数据库

spring.profiles.active

yml文件配置sql server_配置文件_18

-----------------------------------------------------

2个配置文件如下:

创建application-dev.yml,配置开发环境的数据库连接信息

yml文件配置sql server_yml文件配置sql server_19

创建application-test.yml,配置测试环境的数据库连接信息

yml文件配置sql server_配置文件_20


5、修改tomcat端口号

上面的开发环境和测试环境配置里,tomcat的端口号默认都是8080。我们可以单独在不同的yml文件中为每一个不同的环境指定不同的tomcat端口号。

但是没必要,我们就直接在配置在application.yml中配置,让它们共用即可.

yml文件配置sql server_配置文件_21

此时再次重启,浏览器访问,8080就不好使了,需要访问8089端口

yml文件配置sql server_spring_22

那么为什么默认是8080呢,我来带你找一找

1.点开External Libraries

yml文件配置sql server_配置文件_23

2.spring-boot-autoconfigure -->META_INF-->json文件

yml文件配置sql server_yml文件配置sql server_24


SpringBoot 很多注解

1、@SpringBootApplication

@SpringBootApplication注解是组合注解[@SpringBootConfiguration +@ComponentScan + @EnableAutoConfiguration ]

@SpringBootConfiguration 
标注这个类就是配置类,相当于xml配置文件,本质上就是一个@Configuration注解

@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration public @interface SpringBootConfiguration { @AliasFor( annotation = Configuration.class ) boolean proxyBeanMethods() default true; }


@ComponentScan 上帝视角组件扫描

默认扫描启动类所在包及子包下的类身上的注解


@EnableAutoConfiguration 
启用自动配置,自动去读取spring.factories配置文件中的自动配置类

@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<?>[] exclude() default {}; String[] excludeName() default {}; }

下面在自动配置原理中,会详细解释这个注解@EnableAutoConfiguration 


2、@Configuration+@Bean

@Configuration

@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Configuration { @AliasFor( annotation = Component.class ) String value() default ""; boolean proxyBeanMethods() default true; }

@Configuration(proxyBeanMethods = false)

proxyBeanMethods 是用来指定 @Bean 注解标注的方法是否使用CGLIB代理,默认是 true 使用代理。

proxyBeanMethods = false不代理bean方法,每次获取都是重新创建 反之,代理bean方法,代理干的事情:判断这个bean对象是否存在,如果存在就直接在ioc中拿

如果配置类中的@Bean标识的方法之间不存在依赖调用的话,可以设置为false,可以避免拦截方法进行代理操作

@Bean 给容器中添加组件,以方法名作为组件的id,返回类型就是组件的类型,返回的值,就是组件在容器中的实例

@Configuration //告诉springboot这是一个配置类,等同于以前的配置文件
public class MyConfig {
    @Bean//给容器中添加组件,
    App getApp(){
        App app = new App(1, "快手");
        return app;
    }
}

注意:配置类本身也是组件

@Bean 默认是单实例的,不管获取多少次这个组件,都是同一个,

在启动类的面方法中,用 ==判断测试

public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(Spingboot01Application.class, args); //多次获取组件名是getApp的组件 App app1 = run.getBean("getApp", App.class); App app2 = run.getBean("getApp", App.class); //==判断是不是获取的同一个组件 System.out.println(app1==app2); }

控制台打印,符合预期

yml文件配置sql server_spring_25


3、@import+@Configuration

1.@Import要写在容器中的组件类上

2.给容器导入自定义的组件User

@Configuration
@Import(User.class)
public class MyConfig {
}

//---User类是另外一个java文件

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer userId;
    private  String name;
    private  String password;
}

3.import方式导入的组件,默认组件名是全类名

在启动类的main方法里,去获取容器中的组件

@SpringBootApplication public class Application { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(Application.class, args); //获取类型为User的所有组件的beanid String[] names = run.getBeanNamesForType(User.class); //遍历打印beanid for (String name : names) { System.out.println(name); //根据beanId获取容器中的bean User user = (User) run.getBean(name); System.out.println(user); } } }

运行启动类,打印效果如下,@import注入,默认组件名beanid是全类名

yml文件配置sql server_spring_26


4、@ImportResource+@Configuration

作用:迁移spring中xml方式配置的组件

使用方式:在某一个配置类上加@ImportResource

测试如下:

1.创建Phone类,并使用spring的方式在beans.xml中set注入

<bean id="phone" class="com.example.spingboot01.pojo.Phone"> <property name="brand" value="华为"></property> <property name="name" value="mate50Pro"></property> </bean>

2.在配置类上使用@ImportResource导入资源

@Configuration @ImportResource("classpath:beans.xml") public class MyConfig { }

3.在启动类里的main方法获取

public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(Spingboot01Application.class, args); //获取组件名是phone的组件 Object phone = run.getBean("phone"); System.out.println(phone); }

4.控制台打印如下,符合预期效果

yml文件配置sql server_java_27


5、@ConfigurationProperties 配置绑定

该注解源码如下:

//springboot源码
public @interface ConfigurationProperties {
    @AliasFor("prefix")
    String value() default "";

    @AliasFor("value")
    String prefix() default "";
}

因为prefix和value互为别名,下面我就直接省略了,相当于使用了value

---------------------------

配置绑定:将一些配置属性批量注入到bean对象。

配置绑定方式一:@ConfigurationProperties+@Component

prefix=“公共的key值”,但是类中的属性必须和配置文件的属性一致(长得一样,才会自动注入),这种注入方式,属性再多,只要按照规则就可以一次性自动注入。


注意一定要加 @Component

容器中的组件才能拥有springboot给他提供的强大功能,比如配置绑定

@Component @ConfigurationProperties("spring.jdbc.datasource") @Data //提供get、set、toString方法 public class DataSourceProperties { private String driverClassName; private String url; private String username; private String password; }

接着会弹出这么一个玩意

yml文件配置sql server_java_28

解决办法:在pom文件添加配置信息

spring-boot-configuration-processor其实是一个注解处理器,在编译阶段干活的,一般在maven的声明都是 ,optional 为true

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>

---------------------详细介绍如下

optional表示是否会传递依赖,有两个可填值(假如不声明optional标签,默认就是false):false: 传递依赖
true:不传递依赖

举例:A引用了B的依赖,而B又引用了C依赖。 假如B引用C依赖的时候没有设置optional,那么A是可以使用C依赖的。 假如B引用C依赖的时候将optional标签设置为了true,那么在A当中就无法使用C依赖相关的方法,并且A调用B依赖的方法,而B依赖方法使用到了C,这时候会报找不到C依赖下的类,因为C不参与A的打包。

spring-boot-configuration-processor说白了就是给自定义的配置类生成元数据信息的,如上边使用@ConfigurationProperties("spring.jdbc.datasource")的类

项目编译后:

yml文件配置sql server_java_29

生成的内容如下

{ "groups": [ { "name": "spring.jdbc.datasource", "type": "com.xkcoding.properties.property.DataSourceProperties", "sourceType": "com.xkcoding.properties.property.DataSourceProperties" } ], "properties": [ { "name": "spring.jdbc.datasource.driver-class-name", "type": "java.lang.String", "sourceType": "com.xkcoding.properties.property.DataSourceProperties" }, { "name": "spring.jdbc.datasource.password", "type": "java.lang.String", "sourceType": "com.xkcoding.properties.property.DataSourceProperties" }, { "name": "spring.jdbc.datasource.url", "type": "java.lang.String", "sourceType": "com.xkcoding.properties.property.DataSourceProperties" }, { "name": "spring.jdbc.datasource.username", "type": "java.lang.String", "sourceType": "com.xkcoding.properties.property.DataSourceProperties" } ], "hints": [] }name | String 属性的全名。名称采用小写的周期分隔形式(例如server.address)。此属性是强制性的。 type | String 属性的数据类型的完整签名(例如java.lang.String),但也是完整的泛型类型(例如java.util.Map)。 您可以使用此属性来指导用户可以输入的值的类型。为了保持一致性,通过使用其包装对应项(例如,boolean变为java.lang.Boolean)来指定基元的类型。 请注意,此类可能是一个复杂类型,它从Stringas绑定的值转换而来。如果类型未知,则可以省略。 description | String 可以向用户显示的组的简短描述。如果没有可用的描述,则可以省略。建议描述为简短段落,第一行提供简明摘要。描述中的最后一行应以句点(.)结尾。 sourceType | String 贡献此属性的源的类名称。例如,如果属性来自带注释的类@ConfigurationProperties,则此属性将包含该类的完全限定名称。如果源类型未知,则可以省略。 defaultValue | Object | 默认值,如果未指定属性,则使用该值。如果属性的类型是数组,则它可以是值数组。如果默认值未知,则可以省略。

使用additional-spring-configuration-metadata.json进行提示。

yml文件配置sql server_spring boot_30

@Data @ConfigurationProperties(prefix = "developer") @Component public class DeveloperProperty { private String name; private String website; private String qq; private String phoneNumber; }

它使用简单的 JSON 格式,其中的项目分类在 groups 或 properties 下,其他值提示分类在 hints 下

为自定义配置添加 hint 提醒。如自定义的开发人员配置信息

yml文件配置sql server_java_31


配置绑定方式二:@ConfigurationProperties+@EnableConfigurationProperties

某种情况下:我们使用的是第三方的类,人家没标@Component。怎么办,我们也改不了人家的源码

1、在属性类DataSourceProperties上去掉@Component

@ConfigurationProperties("spring.jdbc.datasource") @Data //提供get、set、toString方法 public class DataSourceProperties { private String driverClassName; private String url; private String username; private String password; }

2、一定要在配置类上写,替换了方式一的@Component(是不是一定在配置类上写还有待考究,但是在配置类上写了是可以用的)

使用@EnableConfigurationProperties(DataSourceProperties.class)

@Configuration @EnableConfigurationProperties(DataSourceProperties.class) //开启DataSourceProperties类的配置绑定功能 //把这个DataSourceProperties类组件自动注册到容器中 public class MyConfig { }

经认证:再次启动该测试方法,也是没有问题的。

@SpringBootTest class Spingboot01ApplicationTests { @Autowired DataSourceProperties dataSourceProperties; @Test void contextLoads() { System.out.println(dataSourceProperties); } }

yml文件配置sql server_java_32


6、@Conditional 条件装配

满足Conditional 指定的条件,才进行组件的注入。

它有非常多的派生注解,常用如下 :

注解

作用

@ConditionalOnBean

如果存在某个Bean, 配置类生效

@ConditionalOnMissingBean

如果不存在某个Bean, 配置类生效

@ConditionalOnClass

如果存在某个类, 配置类生效

@ConditionalOnMissingClass

如果不存在某个类, 配置类生效

@ConditionalOnProperty

如果存在某个属性配置, 配置类生效

@ConditionalOnWebApplication

如果是一个web应用, 配置类生效

@ConditionalOnNotWebApplication

如果不是一个web应用, 配置类生效

举例:@ConditionalOnBean

1.条件注解加在方法上,当条件成立后,方法返回的组件才会被注册到容器中

2..条件注解加在类上,当条件成立后,这个类下的所有配置才能生效


SpringBoot自动配置

Springboot在启动的时候会调用run方法,run方法会执行refreshContext()方法刷新容器,

会在类路径下找到springboot-boot-autoconfigure/springboot-boot-autoconfigure.jar/META-INF/spring-factories文件,该文件中记录中众多的自动配置类,

容器会根据我们是否引入依赖是否书写配置文件的情况,将满足条件的Bean注入到容器中,于是就实现了springboot的自动装配

1、@EnableAutoConfiguration

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

2、@AutoConfigurationPackage

直译:自动配置包

@Import@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Import({Registrar.class}) public @interface AutoConfigurationPackage { String[] basePackages() default {}; Class<?>[] basePackageClasses() default {}; }

实际上就是一个@Import,用来给容器中导入一个组件

点击进入Registrar.class

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports { Registrar() { } public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0])); } public Set<Object> determineImports(AnnotationMetadata metadata) { return Collections.singleton(new AutoConfigurationPackages.PackageImports(metadata)); } }

利用Registrar给容器中导入一系列组件,哪一系列??

将指定的一个包(启动类所在包)下的所有组件导入进来。。

原因是从注解@AutoConfigurationPackage的元信息中获取的


3、@Import({AutoConfigurationImportSelector.class})

public String[] selectImports(AnnotationMetadata annotationMetadata) {
    if (!this.isEnabled(annotationMetadata)) {
        return NO_IMPORTS;
    } else {
        AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }
}

this.getAutoConfigurationEntry();//给容器中导入组件

它里面的一个核心方法,

List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);

getCandidateConfigurations();//获取所有导入到容器的配置类

它会使用spring的工厂加载器

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
    return configurations;
}

再往下点点点。。

就会找到这个方法,加载我们所有的组件

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
}

说了这么多,总计就是从这个位置加载文件:META-INF/spring.factories


4、spring-boot-autoconfigure-2.3.7.RELEASE.jar

核心包

yml文件配置sql server_spring boot_33

它里面也有 META-INF/spring.factories

yml文件配置sql server_spring_34

打开这个文件META-INF/spring.factories

从22行一直到148行,正好是127个自动配置类。其实就是在配置文件里写死了,

yml文件配置sql server_java_35

springboot一启动就要给容器中加载的所有配置类,但是这些配置类哪些生效哪些不生效,就是按需开启了。得益于这个条件装配注解@ConditionalOnXXX,实现了按需配置

如查看mvc 的自动配置类:WebMvcAutoConfiguration

yml文件配置sql server_yml文件配置sql server_36


SpringBoot配置文件的查找顺序

1、配置信息来源—环境变量

除了properties文件和yaml文件,配置信息也可以来源于环境变量,也可以是 命令行参数来配置,运行jar包的时候。。。

创建Controller,处理请求

@RestController public class HelloController { @Value("${MAVEN_HOME}") private String msg; @RequestMapping("/hello") public String sayHello(){ return msg; } }

在浏览器访问,真牛逼啊 

yml文件配置sql server_yml文件配置sql server_37


2、配置文件查找位置

在生产环境下修改配置就非常简单了,无需修改代码

由上到下加载,配置文件的查找位置

(1)classpath 根路径(最常用)

(2)classpath 根路径下的config目录

(3)jar包当前目录

(4)jar包当前目录的config目录

(5)/config子目录的直接子目录

情况(5)是指linux目录的根目录下有一个config目录,在这个config目录的子目录是可以用的。

注意:下面的配置(后加载)会覆盖上面的同名项配置


3、验证配置文件加载覆盖

测试情况(1),这也是我们平时配置文件放的位置,在classpath根路径

yml文件配置sql server_java_38

文件内容是:

yml文件配置sql server_spring_39


@RestController public class HelloController { @Autowired DataSourceProperties dataSourceProperties; @RequestMapping("/hello") public String sayHello(){ return dataSourceProperties.getUsername()+":"+dataSourceProperties.getPassword(); } }

浏览器访问,没啥问题,这是我们测试别的情况的基础

yml文件配置sql server_spring boot_40

测试情况(1)和情况(2)同时存在的情况

配置文件的位置

yml文件配置sql server_配置文件_41

文件内容,只修改了这一处 

yml文件配置sql server_spring_42

 浏览器访问测试,没啥问题。后加载的配置会覆盖之前同名的配置

yml文件配置sql server_yml文件配置sql server_43

测试情况(1)和情况(2)测试情况(3)同时存在

使用idea打包后,创建测试文件夹,把jar包放到文件夹中,并创建application.yml

yml文件配置sql server_spring_44

 对配置文件内容作如下修改

yml文件配置sql server_yml文件配置sql server_45

打开cmd, java - jar 运行我们的springboot项目

 

yml文件配置sql server_yml文件配置sql server_46

 在浏览器访问测试,符合预期效果

yml文件配置sql server_yml文件配置sql server_47

测试情况(1)、情况(2)、情况(3)、情况4 同时存在

在jar包所在目录创建config文件夹,并在文件夹里创建配置文件

yml文件配置sql server_spring boot_48

 配置文件内容作如下修改

yml文件配置sql server_配置文件_49

 浏览器访问测试,符合预期效果

yml文件配置sql server_yml文件配置sql server_50

总结一波

Springboot 程序启动时,会从以下位置查找配置文件并加载:

  1. 当前项目根目录下的/config目录下
  2. 当前项目的根目录下
  3. classpath:/config/:classpath的/config目录(即resource目录下的config目录)
  4. classpath:/ :classpath的根目录(即resource目录下)

配置文件加载优先级为由上至下,上面的优先级更高,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容。


SpringBoot错误处理机制

1、默认错误处理机制

默认情况下:springboot提供/error 处理所有错误的映射

对于机器客户端(如postman),它将生成JSON响应,其中包含错误。HTTP状态和异常消息的详细信息。

对于浏览器客户端,响应一个"whitelabel"错误视图,以HTML格式呈现相同的数据