在Spring家族中提供了很多优秀的框架,所有的框架都是基于同一个基础框架——Spring Framework.
使用spring框架开发麻烦的一批,光是搞依赖和配置就够人喝一壶了。因此在spring4.0版本之后又推出了springboot框架。springboot框架用起来比spring框架简单的多了。
在springboot的底层提供了两个重要的功能。
起步依赖——简化了pom文件中依赖的配置,解决了依赖配置繁琐的问题。
自动配置——简化了bean的声明以及bean的配置。
起步依赖原理
使用spring开发时用到什么就需要引入什么依赖,比如进行web开发要webmvc的依赖,servlet的依赖,json的依赖,用到aop还要引aop的依赖。
在springboot当中要进行web开发只需要引入一个web开发的起步依赖
spring-boot-starter-web,如果有aop的需求就引入spring-boot-starter-aop。
Maven依赖传递
这里利用maven的依赖传递,springboot提供的起步依赖当中就提供了当前程序开发需要的所有常见依赖,如spring-boot-starter-web中就有了web开发的所有常见依赖
自动配置原理
研究自动配置就是在研究引入了依赖之后以如何把依赖的jar包里面的bean对象以及配置注入到本项目的IOC容器当中去的。 在下面运行的项目工程中,运行之后可以看见Bean里面有一个appliction,里面放着的就是所有的这个项目中所有bean对象,在没有高亮的bean对象里面可以看见我在项目中自己添加注解的bean对象,有Controller层的,有Mapper层的,还有一个Service层的,其他的高亮的Bean对象应该就是依赖包里面定义好的bean对象,在项目运行时自动加载进来。
面试当中问SpringBoot的原理就是在问自动配置的原理
模拟案例
如上图所示,准备两个项目,其中一个模拟外部的依赖jar包
项目结构图如下所示
在我们的项目工程中要使用第三方提供的项目依赖就要将其坐标导入进去。上图中画红圈的地方就是上面那个项目坐标。
例如在模拟第三方的项目中有一个HeaderConfig类,其自身加了一个Configguration注解表明其实一个配置类,里面有两个Bean对象。
在下面的正式项目的测试类当中进行测试
在test目录下有一些测试方法如下所示,定义了一个IOC容器用来获取第三方的Bean对象。
报错
直接运行测试后会报错显示没有找到这个类型的Bean对象
三个都是会报同一个错误。
说明导入的第三方的Bean和配置类没有生效。
原因:没有被组件扫描扫到。
在项目的启动类的注解@SpringBootApplication注解具有包扫描的作用,但是它的作用范围只到当前包以及它的子包。
当前包就是itheima.
解决方案(1)(不推荐:):
通过一个注解@ComponentScan组件扫描进行指定包的扫描
这里不仅要选择要扫描的第三方包,还要指定当前包,因为一旦显示指定扫描区域,原来默认扫描的区域会被覆盖。
因此加上上面的注解之后再次运行测试就可以成功拿到IOC容器中的Bean对象。
另外的那些Bean对象也可以成功获取。
解决方案(2):
通过上面的解决方案1我们会发现,如果引入其他很多比如mybatis,lombok之类的以来都要这样用componentscan注解扫描的话会多出很多要扫描的包。但是很明显没有这么做
通过import导入的所有类都会自动加入IOC容器中。
导入普通类
即使这个类本身没有加任何注解也是可以的
在测试类当中可以成功获取其Bean对象。
导入配置类
这个会将该配置类下所有Bean对象放入IOC容器当中
在测试类当中可以成功获取其Bean对象。两个都可以成功获取到
导入ImportSelector接口的实现类
这个接口下有一个selectImports的方法返回一个String[]数组,里面都是需要交个IOC容器管理的类的全类名。
在下面实现这个接口后往里面放一个配置类的全类名,也就是这个配置类会被注入到IOC容器当中
进行导入测试
在测试类当中调试输出可以获得配置类下的两个Bean对象
但是在使用这种方式导入时还是要清楚的知道这个第三方依赖有哪些个selectImports接口的实现类。只有第三方依赖自己知道自己有哪些类,所以要在第三方依赖当中定义一个注解把自己本身selectImports接口的所有实现类都放进去,然后我们的项目中直接只加个注解即可。
使用@Enablexxxx注解(SringBoot内部采用的方式)
比如下面这个EnableHeaderConfig注解,已经把自己内部selectImports的实现类放进去了。
所以直接在我们的项目中使用这个注解即可
调试输出可以获取到第三方中的Bean对象。