SpringBoot的自动装配原理


前言

Spring是目前世界上最流行的Java框架,它可以帮助我们更加快速、更加容易的来构建Java项目。但是使用的时候却很繁琐,这繁琐体现在:①在pom.xml中依赖配置比较繁琐(下jar包) ②在使用Spring框架进行项目开发时,需要在Spring的配置文件中做大量的配置。

基于Spring存在的问题,官方在Spring框架4.0版本之后,又推出了一个简化Spring开发的全新的框架:SpringBoot。注意哈,是简化,不是替换~


一、SpringBoot为什么使用更简洁?

SpringBoot提供了两个核心技术:①起步依赖 ②自动装配

通过SpringBoot所提供的起步依赖,就可以大大的简化pom文件当中依赖的配置,从而解决了Spring框架当中依赖配置繁琐的问题。

通过自动配置的功能就可以大大的简化框架在使用时bean的声明以及bean的配置。我们只需要引入程序开发时所需要的起步依赖,直接使用就可以了。

二、SpringBoot - 起步依赖

使用过spring开发的小伙伴都吃过引入依赖的苦,比如在使用web开发的时候,就要引入好多web相关依赖,并且这些分散的依赖还要保证它们的版本互相匹配,不然真的跑不起来。
在这里插入图片描述

而在SpringBoot中就仅仅需要在pom文件里面引入一个启动器就可以了。
在这里插入图片描述

引入了这个依赖以后,我们看一下Maven里面都有啥~

在这里插入图片描述
原来这一个启动器就帮我们自动引入了这么多依赖。

其实这都是起步依赖的功劳。起步依赖的原理就是利用了依赖的可传递性,引入一个依赖,就可以通过这一个依赖引入其他依赖。

三、SpringBoot - 自动装配

3.1、什么是自动装配

起步依赖我们学完了,那么pom文件里面的依赖又是怎么引入到SpringBoot项目里面去的呢?

这就要归功于SpringBoot的自动装配了~

什么叫自动装配呢?用比较官方的话来说,SpringBoot的自动配置就是当Spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。

举个例子:我们在编写controller层的代码的时候,用@Autowirte注入了service层的对象,那么请问你在使用对象之前有将service层的对象交给IOC管理吗?

我们发现这些都不用我们手动去实现,直接使用就可以了,极大简化了我们的开发效率,省去了繁琐的配置操作。

简化确实简化了许多,但是不能开发了这么久而不知道其原理叭。

3.2、把bean对象交给IOC的三种方式

在学习自动装配前需要知道bean对象怎么交给IOC管理,有三种方式:

方式一: 在类上打@Component注解,controller、service、Repository都是component的衍生注解。

不信?按住ctrl键+鼠标左键,点@Controller进去看看。
在这里插入图片描述
@Service也是一样的。
在这里插入图片描述

有@Component注解的类,SpringBoot在启动的时候,就会把这个类的实例对象加载到IOC容器中。

方式二: 在启动类中添加@Bean注解,注入bean对象。
在这里插入图片描述
但是这样写就会显得启动类很不优雅,不推荐这样做!

方式三: 解决方式二不优雅的问题,在任意类上加@Configuration注解,这个注解会将这个类标志为配置类,然后在这个配置类里面加入@bean注解。效果与方式二一致。

在这里插入图片描述

3.3、自动装配 - 当前模块

我们先来看看在当前这个模块中(启动类所在的模块),SpringBoot是怎么将对象添加到IOC容器的。

当一个SpringBoot项目启动的时候,就会最先扫描启动类上面的注解:@SpringBootApplication

第一步: (ctrl+鼠标左键点进去)这个注解主要有三个注解:
在这里插入图片描述

@SpringBootConfiguration:这个注解与@Configuration注解的作用相同,用来声明当前也是一个配置类。

@EnableAutoConfiguration:SpringBoot实现自动配置的核心注解。

@ComponentScan:组件扫描,默认扫描当前启动类所在的包,及其自包。

第二步: 我们要研究自动配置,肯定就是要点进去@EnableAutoConfiguration,这个注解主要有两个注解:
在这里插入图片描述

@AutoConfigurationPackage:负责扫描启动类包,及其子包下的注解。

@Import(AutoConfigurationImportSelector.class):负责扫描引入的依赖的注解。

第三步: 我们要研究的是本类的自动配置,因此我们应该点进去@AutoConfigurationPackage注解,这个注解主要导入了一个AutoConfigurationPackages类的Registrar( )方法:
在这里插入图片描述

第四步: 直接点进Registrar( )方法里面,我们就可以看到一个register( )方法
在这里插入图片描述
按住ctrl键不放,将鼠标移动到这个方法上,不要点,看看这个方法的参数

在这里插入图片描述
第二参数其实就是一个包名。具体是什么名字呢?
在旁边打断点,Debug一下:
在这里插入图片描述
我们发现,其实就是在这里,定义了扫描哪个包的注解。也就是说,当SpringBoot项目启动的时候,就会扫描启动类所在的包,及其子包下的所有注解,只要是含有上述@Component和@Bean注解的类,都会被加载到IOC容器中。

3.4、自动装配 - 外部模块

第一步: 续接3.3的第二步,我们讲到有一个@Import注解,它负责扫描引入的依赖的注解。它导入了一个AutoConfigurationImportSelector类,这个类实现了DeferredImportSelector接口,而DeferredImportSelector接口又继承了ImportSelector接口。在ImportSelector接口中有一个方法是selectImports( ),因为AutoConfigurationImportSelector是它的子接口的实现类,因此必须重写这个方法。而这个方法的返回值就是一个字符串的数组。
在这里插入图片描述
第二步: 我们在AutoConfigurationImportSelector类中找到这个方法:
在这里插入图片描述
找到selectImports( )方法后,我们发现它的返回值来自autoConfigurationEntry对象,而这个对象由来自于getAutoConfigurationEntry( )方法.
第三步: 点进去这个方法:

在这里插入图片描述
我们发现getAutoConfigurationEntry( )方法的返回值,是new了一个AutoConfigurationEntry对象,这个对象的作用是为了存储两个参数,分别是configurations和exclusions

configurations就是要导入的依赖
exclusions就是要排除的依赖

第四步: 我们就看导入的,导入的依赖又来自于getCandidateConfigurations( ) 方法,继续点进去
在这里插入图片描述

我们发现这里有一段message,它的意思是:如果您使用的是自定义打包,在 META-INF/spring.factory 和 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 中找不到自动配置类。请确保该文件正确无误。

说通俗一点就是,这两个包存放了所有自动配置类,如果这两个包都没有你想要的配置类,估计就是你写错了,只要你写对了,我都存到这两个文件里面了。

呐这两个包又在哪儿呢?

第五步: 其实就在最左边工程目录的External Libraries里面存放着
在这里插入图片描述

注意哈

在这里插入图片描述
我们找的时候,就直接找spring-boot-autoconfigure,版本是2.7.10,不一定是我这个版本,看你们当前使用的是哪个版本

在这里插入图片描述

点开这两个类,里面存放的都是需要导入的配置类的包名路径了。外部的依赖,都存在这里。SpringBoot项目启动的时候,就会将这里面的配置类加载进IOC容器中,以备程序员使用。

注意

在这两个文件中,并不是所有的配置类,都要加载到IOC容器中,不然的话,SpringBoot项目会启动的非常慢。既然是选择性加入,就要用到一个注解:@Conditional。

这个注解的作用就是:按照一定的条件进行判断,在满足给定条件后才会注册对应的bean对象到Spring的IOC容器中。

而@Conditional本身是一个父注解,派生出大量的子注解:

  • @ConditionalOnClass:判断环境中有对应字节码文件,才注册bean到IOC容器。
  • @ConditionalOnMissingBean:判断环境中没有对应的bean(类型或名称),才注册bean到IOC容器。
  • @ConditionalOnProperty:判断配置文件中有对应属性和值,才注册bean到IOC容器。

总结

充电时刻
SpringBoot的自动装配原理就是:

①在启动类中的所在包及子包中,直接扫描注解,然后添加到IOC容器中。

②通过类加载器,去获取classpath中配置文件 META-INF/spring.factory 和spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports两个包。

③然后筛选出以EnableAutoConfiguration.class为key的,符合条件的配置类。

④通过@Conditional注解过滤掉不需要加载到IOC容器的对象。

⑥将符合条件的配置类加载到IOC容器中。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值