SpringBoot原理

SpringBoot开发项目,为什么这么简单?SpringBoot帮我们做了哪些事情?

了解SpringBoot的底层原理是有必要的。

面试重点

spring框架中各种jar包的依赖关系(还有各种jar包的版本适配)、还有各种配置非常繁琐



SpringBoot的两个优点:起步依赖、自动配置

springboot除了我们自己定义的bean对象和引入的第三方bean。还会自己配置一些配置的bean对象存入到IOC容器中,当我们需要使用时,直接使用@Autowired注入即可,从而简化了开发



加载bean对象的(即bean如何加载到spring的IOC容器中的)方法:

我们研究SpringBoot的自动配置原理,就是研究当我们在maven中引入依赖后,是如何将依赖jar包当中的所定义的配置类,以及这些bean如何加载到spring的IOC容器中。

方法1:通过@ComponentScan组件扫描的方式

通过@ComponentScan组件扫描的方式,添加第三方的bean到SpringIOC容器中

场景:当前在SpringBootWebConfig2Application的启动类中要使用itheima-utils包下的bean对象

(1)我们需要在springboot-web-config2中的pom依赖中引入itheima-utils依赖

(2)虽然itheima-utils包中的的自定义bean对象已经加了@Component注解,交由IOC容器管理,但是在在SpringBootWebConfig2Application的启动类中仍然访问是访问不到的。

因为SpringBoot的启动类默认只扫描当前包com.itheima,及其子包的bean对象

(3)此时,我们必须还要加上@ComponentScan注解来指定扫描包是"com.example"。但是会覆盖原有的扫描包。所以还要加上本地的扫描包

注意:为什么这里能扫描到"com.example"呢,因为加了上面的依赖,所以它知道去哪扫描,是扫描itheima-utils目录下的"com.example"路径

扫描包为多个,怎么书写?

@ComponentScan直接用value属性指定多个扫描包,即@ComponentScan({"xxx","xxx"})

或者

用@ComponentScan的basePackages属性指定多个扫描包

这样就可以扫描到第三方包的bean对象



开发SpringBoot项目,其实也引入了很多其他的第三方依赖,要想完成自动如果都以方法1书写,那@ComponentScan后面要加很多的扫描包

方法2:使用@Import导入

(1)导入itheima-utils中的普通类,这个类上不用加任何的注解,包括@Component

(2)导入itheima-utils中的配置类

(3)实现ImportSelector接口的实现类,重写里面的selectImports方法 ,返回值 表示 要交给IOC容器管理的

再在启动类上使用**@Import** 导入ImportSelector接口的实现类即可

这里我们要导入bean对象,还要知道要导入的类名,还是比较繁琐

要导入第三方的bean对象,只有第三方自己最清楚

方法3:以注解的形式导入

这个第三方定义的注解里面,使用了Import,导入了需要的bean,我们再使用这个bean对象的时候,只需要加上这个注解@EnableHeaderConfig即可,这个注解的@EnableHeaderConfig里面帮我们导入了需要的bean对象交给IOC容器管理

SpringBoot官方就是采用的第三种加注解的方式来导入bean对象



SpringBoot自动加载的原理

先要从启动类开始

(1)理解启动类上的注解@SpringBootApplication

@SpringBootApplication点进去

@SpringBootApplication作为一个注解,前4个都是作为注解的原注解

看第5个注解@SpringBootConfiguration,点进去

就只有定义了一个配置类的注解@Configuration,所以我们才可以在启动类上使用@Bean注解来导入第三方的类对象,来交给IOC容器管理

第7个注解,就是定义包扫描路径的,所以启动类只能扫描到当前包及其子包,将其中的bean对象交给IOC容器管理

自动配置的核心就是第6个注解@EnableAutoConfiguration

(1)@EnableAutoConfiguration 就是那个**@Import注解**,通过@Import注解来导入指定的bean或者配置类

(2)@Import注解,通过导入ImportSeletor(接口)实现类的方式,导入bean对象交给IOC容器管理

AutoConfigurationImportSeletor 就是ImportSeletor(接口)的实现类

AutoConfigurationImportSeletor里面重写selectImports方法

selectImports方法的返回值 表示 我需要将哪些类 交给IOC容器管理(返回值是字符数组,且类要指定全类名)

然后 selectImports方法 会去读取两份配置文件 ,在这两份配置文件中指定了大量需要自动配置的类

这两份配置文件在起步依赖中,好像 不同的起步依赖 包含的 这两份文件 都是一样的

这里面都是一个个配置类 的全类名,然后会加载每个配置类中用@Bean注解的bean对象交给IOC容器管理

配置类 中所有被**@Bean注解的bean对象** 都会直接交给IOC容器管理吗?并不是的。发现@Bean注解旁边还有**@ConditionalOnMissingBean注解**

@ConditionalOnMissingBean注解:这个注解的作用,就是按条件装配 ,当满足一定的条件之后,才会把这个bean注册到IOC容器中



@Conditional是条件装配的注解

可以加在类上,也可以加在方法上

(1)加在配置类上:对配置类中所有加了@Bean注解的都生效

(2)加在方法上:只对这一个加了@Bean注解的方法生效

第一个注解:

因为pom文件中已经引入了jwt依赖,这样环境中就有jwts对应的字节码文件,所以Headerparse这个bean会直接交给IOC容器管理

如果pom文件中去掉了jwt依赖,则IOC容器中不会有Headerparse这个bean

第二个注解:

使用场景:声明一个默认的bean对象,如果用户自己声明了这个bean对象,则这个bean不会生效,如果用户没有声明这个bean对象,还想使用这个bean,那么这个默认的bean对象就会生效

第三个注解:

配置文件中有这个属性和这个值,才会正常将该bean加入到IOC容器中

如果有这个属性,值不符合,也不会有这个bean。

第三个注解的使用场景:在SpringBoot中整合其他第三方的技术的时候,我们只有在对应的配置文件中,配置了对应的配置项,它才会声明对应的bean对象。



自定义Starter

有很多的第三方技术,它是没有起步依赖的,但是这个技术,在项目开发中又很通用,那么我们直接使用,使用起来就会比较繁琐

我们需要引入对应的依赖,在配置文件中进行配置,还需要基于官方SDK示例来改造对应的工具类,然后在项目中我们才可以使用。

例如,我们使用aliyunOss需要这么多的步骤,别的开发也需要这么多的步骤

第一个是springboot官方提供的起步依赖

下面两个是第三方提供的起步依赖 ,通常是命名方式是 功能在前, 一看就是mybatis或者pagehelper整合springboot所提供的起步依赖

相关推荐
前行的小黑炭20 分钟前
设计模式:为什么使用模板设计模式(不相同的步骤进行抽取,使用不同的子类实现)减少重复代码,让代码更好维护。
android·java·kotlin
Java技术小馆25 分钟前
如何设计一个本地缓存
java·面试·架构
XuanXu1 小时前
Java AQS原理以及应用
java
风象南4 小时前
SpringBoot中6种自定义starter开发方法
java·spring boot·后端
mghio13 小时前
Dubbo 中的集群容错
java·微服务·dubbo
咖啡教室18 小时前
java日常开发笔记和开发问题记录
java
咖啡教室18 小时前
java练习项目记录笔记
java
鱼樱前端19 小时前
maven的基础安装和使用--mac/window版本
java·后端
RainbowSea19 小时前
6. RabbitMQ 死信队列的详细操作编写
java·消息队列·rabbitmq