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所提供的起步依赖

相关推荐
哎呦没17 分钟前
SpringBoot框架下的资产管理自动化
java·spring boot·后端
2401_8576009520 分钟前
SpringBoot框架的企业资产管理自动化
spring boot·后端·自动化
m0_571957582 小时前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
魔道不误砍柴功4 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2344 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨4 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
种树人202408194 小时前
如何在 Spring Boot 中启用定时任务
spring boot
测开小菜鸟6 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity7 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天7 小时前
java的threadlocal为何内存泄漏
java