java进阶之了解SpringBoot的配置原理

 更新时间:2021年06月04日 12:00:04   作者:梦里一明月  
今天带大家了解SpringBoot的相关知识,文中对SpringBoot的配置原理作了非常详细的图文示例及介绍,需要的朋友可以参考下

一、Spring Boot的特点

首先我们要知道 Spring Boot 在底层已经为我们添加好了很多依赖。比如我们常用的Tomcat,Spring,SpringMVC这些,甚至连mysql数据库的依赖也为我们添加好了

在这里插入图片描述

不过 SpringBoot 2.5.0 使用的mysql依赖版本是8.0.25的,如果还在使用 mysql 5 版本的小伙伴们就需要在项目的 pom.xml 文件中再次指定自己所用的依赖版本号。(因为 maven 在引入依赖时采取就近原则,你如果指定了依赖版本号的话,它会加载离它近的,而不会去加载远的)

在这里插入图片描述

例如,我要修改 mysql 依赖的版本为5.1.43

//在当前项目里面重写配置
    <properties>
        <mysql.version>5.1.43</mysql.version>
    </properties>

二、了解容器的功能

添加组件

@Configuration、@Bean注解

首先,这个注解是写在类上面的,告诉 spring boot 这是一个配置类,等同于 以前的配置文件

配置类里面使用@Bean标注在方法上给容器注册组件,默认情况下是单例的。以方法名就是组件的 id 。返回类型就是组件类型。返回的值,就是组件在容器中的实例

为什么他会是单例的呢? 原因是在@Configuration注解的源码中,还定义了一个属性 proxyBeanMethods ,默认值是 true。

在这里插入图片描述

当然我们也可以修改他的值为false,这样他就会创建多个对象了。

举个例子:

在这里插入图片描述

我现在在配置类里面定义了一个组件,他会返回一个 User 对象,当proxyBeanMethods = true 时,无论调用多少次 user01() 方法,在容器中都只会存在一个实例对象,但我现在把它改为 false ,来测试一下他到底是不是能创建多个实例了。

在主方法中进行测试:

User user=config.user01();
    User user1=config.user01();
    System.out.println(user==user1);

最后输出的结果是

false

这就说明现在创建了两个对象了,在容器中useruser1并不是指向同一块内存地址

那我们什么时候可以把它改成 false 来使用呢? 这就要设计到两种编写Spring Boot的方式了

  • 一种是FULL模式 全模式(单例)
  • 另一种是Lite模式 轻量级模式(非单例)

如果有组件依赖必须使用Full模式(默认)。其他默认是否Lite模式

Import注解

加入 IOC 容器的方式有很多种,上面的@Bean是一种,这里提到的@Import也是用来注册组件的,@Import注解可以用于导入第三方包 (当然@Bean也可以)

它是写在类上面的,

在这里插入图片描述

它所创建的组件 id 默认是类的全限定名称

在这里插入图片描述

具体用法参考:b站Spring注解驱动教程

Conditional注解

条件装配:满足Conditional指定的条件,则进行组件注入

@Conditional注解下面还有许多的子注解

在这里插入图片描述

因为它的子注解实在太多了,下面我们具体实现一个例子来说明一下它的功能

先在 User 类中再加入一个 Pet 属性

在这里插入图片描述

现在我希望容器在没有 Pet 的情况下,我也不要 User 对象

要实现这个需求,可以这样做,在 User 组件前面添加@ConditionalOnBean注解,并指定条件为 Pet 组件的 id 来进行限制

在这里插入图片描述

执行测试方法

在这里插入图片描述

运行结果:

容器中是否有tomcat:false
容器中是否有user:false

这样就对组件 User 的注册加以限制了

也可以把@ConditionalOnBean(name="tom")注解加在配置类上面,当容器中有 tom 组件时,这个类中的其他组件才会生效,否则不生效

三、原配置文件的引入

如果你原有的项目还是使用 beans.xml 等配置文件的方式来注册组件的话,SpringBoot 是肯定无法自动配置的,那怎么样才能让SpringBoot用我这个配置文件去注册组件呢?

@ImportResource注解

使用@ImportResource注解可以引入以前那种 xml 配置文件的方式写的组件

使用方法:直接加在现在的配置类上面,例如:

@ImportResource("classpath:beans.xml")

配置绑定

配置绑定是什么意思呢?其实就是使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用

具体做法:使用@ConfigurationProperties注解

这个注解是加在你需要从 properties 属性配置文件中要导入的属性的类上面。

比如:我现在写了一个 Car 类,然后在 properties 文件中写好了它的属性

在这里插入图片描述
在这里插入图片描述

( 注意:properties 文件中的所有属性均要小写,驼峰命名法也不行,可以用 - 或 _ 来代替 )

我们想要将配置文件中定义好的属性绑定到实例对象上的话,就可以在 Car 这个类上面加上@ConfigurationProperties(prefix = "mycar")prefix 代表前缀的意思。

在这里插入图片描述

单加上这一个注解还不行,因为此时容器中还没有这个对象,可以采用两种方式来把 Car 这个对象加入容器中:

1.使用@Component注解

2.使用@EnableConfigurationProperties注解

@Component+@ConfigurationProperties

@ConfigurationProperties注解上方加上@Component注解,即可将 Car 加入到容器中

测试方法:

在这里插入图片描述

运行,访问 “/car” 查看结果

在这里插入图片描述

@EnableConfigurationProperties+@ConfigurationProperties

使用@EnableConfigurationProperties注解则需要在配置类上面添加,而不是 Car 上面

在这里插入图片描述

这个注解的作用就是

1.开启Car的属性配置功能

2.把这个Car这个组件自动注册到容器中

再次运行程序,可以得到相同的结果

在这里插入图片描述

四、自动配置原理

说完上面这些,我们来看一下,Spring Boot是如何实现自动装配的

引导加载自动配置类

我们先点进@SpringBootApplication的源码中去,发现它其实是3个注解的合成注解:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

在这里插入图片描述 

@SpringBootConfiguration

其中,@SpringBootConfiguration的源码底层使用了@Configuration注解,说明它其实也是一个配置类,只不过它相当于是一个主配置。

@ComponentScan

根据我们之前的学习,这个注解其实就是一个组件扫描器的作用,是Spring的注解

@EnableAutoConfiguration(核心)

最关键最核心的注解就是这个,@EnableAutoConfiguration

@AutoConfigurationPackage

我们点进它的源码里面去,发现它底层调用了一个叫@AutoConfigurationPackage的注解,翻译过来就是自动配置包,它指定了默认的包规则

在这里插入图片描述

再继续查看它的底层源码,发现它导入了一个叫Register的组件

在这里插入图片描述

点进去,给它打上一个断点,来看一下到底是如何运作的

在这里插入图片描述

代码现在在这里停住了,让我们来看一下这一行代码里面,发现它能够找到我们所在的包名,由此我们也就能知道为什么 Spring Boot 能够将指定的一个包下的所有组件导入进来了,

在这里插入图片描述

@Import({AutoConfigurationImportSelector.class})

@EnableAutoConfiguration注解下还有一个注解,它是干什么的呢?让我们看一下源码就知道了

在这里插入图片描述

AutoConfigurationImportSelector类下面我们找到了一个方法getAutoConfigurationEntry(annotationMetadata),它是用来给容器中批量导入一些组件的

在这里插入图片描述

给他打一个断点,看看到底加入了些什么组件进容器里

在这里插入图片描述

说明这 131 个对象都是要加入到容器中的,并且都存储在了一个List集合当中 List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes)

在这里插入图片描述

为什么会是131个呢? 其实是Spring Boot 里面写死了,一启动就要给容器中加载的所有配置类

打开spring-boot-autoconfigure-2.5.0.RELEASE.jar下META-INF/spring.factories位置的文件,让我们来看一下源码是怎么写的

在这里插入图片描述

这里写了一大堆 xxxxAutoConfiguration 的配置类,从26行开始,到156行结束,刚好是 131 个。

在这里插入图片描述
在这里插入图片描述

虽然我们 131 个场景的所有自动配置启动的时候默认全部加载,但并不是都会生效的,比如 AOP 的部分功能就需要你导入 aspectj 相关的包才能生效。它是按照条件装配规则(@Conditional),最终会按需配置。

如图, aspectj 是爆红的

aspectj相关的包是爆红的

除了AOP之外,还有一些类也是没有生效的(比如CacheAutoConfiguration),这里就不再赘述了,感兴趣的同学可以去看源码了解一下。

五、修改默认配置(约定大于配置)

SpringBoot 默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先

以 SpringMVC 中的文件上传解析器为例,他在容器中的默认名字是multipartResolver,但是我们写代码的时候可能不知道底层源码里面给他的默认名字是这个,我们给他起了另外一个名字,这个时候 SpringBoot 就会去容器中找到你所配置的那个组件,并且返回那个组件,也就是下面这段代码:

在这里插入图片描述

这是为了防止有些用户配置的文件上传解析器不符合规范。

六、总结

  • SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
  • 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定
  • 生效的配置类就会给容器中装配很多组件
  • 只要容器中有这些组件,相当于这些功能就有了
  • 定制化配置
  • 用户直接自己@Bean替换底层的组件
  • 用户去看这个组件是获取的配置文件什么值就去修改。

整个的流程:xxxxxAutoConfiguration —> 组件 —> xxxxProperties里面拿值 ----> application.properties

所以,当我们需要修改组件的配置的时候,只需要在application.properties里面进行配置即可

到此这篇关于java进阶之了解SpringBoot的配置原理的文章就介绍到这了,更多相关SpringBoot的配置原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringMvc微信支付回调示例代码

    SpringMvc微信支付回调示例代码

    微信一直是一个比较热门的词汇,今天这篇文章主要介绍的是SpringMvc微信支付回调的示例代码,对大家开发微信支付具有一定的参考借鉴价值,下面来一起看看吧。
    2016-09-09
  • Java中几种常用数据库连接池的使用

    Java中几种常用数据库连接池的使用

    数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的连接数据库对服务性能来讲是一个瓶颈,使用缓冲池技术可以来消除这个瓶颈,本文就来介绍Java常见的几种,感兴趣的可以了解一下
    2021-05-05
  • MybatisPlus分页失效不起作用的解决

    MybatisPlus分页失效不起作用的解决

    在使用MybatisPlus的selectPage时发现分页不起作用,每次返回的都是全部的数据,本文就来介绍一下MybatisPlus分页失效不起作用的解决,感兴趣的可以了解一下
    2024-03-03
  • Spring Boot 集成 Kafkad的实现示例

    Spring Boot 集成 Kafkad的实现示例

    这篇文章主要介绍了Spring Boot 集成 Kafkad的示例,帮助大家更好的理解和学习使用Spring Boot框架,感兴趣的朋友可以了解下
    2021-04-04
  • 用JAVA实现杨辉三角实例

    用JAVA实现杨辉三角实例

    大家好,本篇文章主要讲的是用JAVA实现杨辉三角实例,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • 详解JVM的分代模型

    详解JVM的分代模型

    这篇文章主要介绍了JVM的分代模型的相关资料,帮助大家更好的理解和学习Java虚拟机相关知识,感兴趣的朋友可以了解下
    2020-10-10
  • Java C++题解leetcode769最多能完成排序的块

    Java C++题解leetcode769最多能完成排序的块

    这篇文章主要为大家介绍了Java C++题解leetcode769最多能完成排序的块示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • SpringBoot整合Swagger2实例方法

    SpringBoot整合Swagger2实例方法

    在本篇文章里小编给大家整合了关于SpringBoot整合Swagger2的相关知识点内容,有兴趣的朋友们学习下。
    2019-06-06
  • IDEA的常见的设置和优化功能图文详解

    IDEA的常见的设置和优化功能图文详解

    这篇文章主要介绍了IDEA的常见的设置和优化功能,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • 图解Java经典算法希尔排序的原理与实现

    图解Java经典算法希尔排序的原理与实现

    希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一。本文会以图解的方式详细介绍希尔排序的基本思想及其代码实现
    2022-09-09

最新评论