Spring Boot的启动就两个很难以理解的问题
一、为什么没有引入相关的jar包就可以直接用SpringMVC的功能了呢?
1、前面写那个helloworld的时候导入了一个父项目的坐标和一个依赖,我们先点进父项目的坐标看看。
2、 发现父项目中还有一个父项目再点进去
3、进去我们发现里面有一堆我们日常需要的依赖版本定义,比如activemq,aspectj等。
由此我们可以得出结论,引入的父项目坐标就是为我们引入的依赖做版本控制用的,所以在spring-boot-dependencies中定义好了的我们再引入不需要写版本了,没有的就需要自己定义版本。那依赖又是在哪里导入的呢?
这时候我们进入官网找到对应的文档找到对应的描述,称其为starter(启动器),SpringBoot将所有的功能场景抽取出来做成一个个的starter,在项目中引入starter相关场景的依赖也会被导入进来。要什么功能导入什么starter
点击spring-boot-starter-web,我们就能看到相应的依赖了。
二、之前使用Spring或者SpringMVC的时候都需要一堆配置,譬如HandlerMapping,HandlerAdapter等。那么这些配置是怎么生成的呢?
点击@SpringBootApplication注解中看看,其他的都是元注解,主要就框住的那两个
1、点进@SpringBootConfiguration注解看发现该注解上有个@Configuration注解,@Configuration注解是Spring的注解,其意是被该注解标注了该类就是一个配置类,
配置类相当于配置文件 配置类也是容器中的一个组件:@Component
1.1、结论:@SpringBootConfiguration注解的作用:被标注的类就是一个配置类,就像xml配置文件,而现在是用java配置文件。并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到spring容器中,并且实例名就是方法名。
1.2、可以直接这样获取
2、开始说@EnableAutoConfiguration注解,我们点进去看又有两个重要的注解
@AutoConfigurationPackage,@Import
2.1、点进@AutoConfigurationPackage注解看发现有个@Import注解,该注解也是Spring中的底层注解。我们点进Registrar这个类,发现该类是个静态类,给registerBeanDefinitions方法打上断点,debug运行
2.1.1、
(new AutoConfigurationPackages.PackageImport(metadata)).getPackageName()得到的包名正是被@SpringBootApplication所标注类的包下。
2.1.2、结论:@AutoConfigurationPackage作用:将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;
可以自行测试在别的包下使用SpringMVC。
2.2、点进@Import注解上的AutoConfigurationImportSelector类
2.2.1、发现有个selectImports方法。该方法会调用当前对象getAutoConfigurationEntry()方法,点进去并打上断点,debug启动。
2.2.2、该方法最终得到一个List集合,该集合中的值就是配置类的全类名,将所有需要导入的组件以全类名的方式返回;(比如里面有aop,批处理等配置)
2.2.3、通过该集合实例化一个AutoConfigurationImportSelector.AutoConfigurationEntry对象并返回到selectImports方法。
2.2.4、selectImports拿到该集合并返回
所以有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;
在spring-boot-autoconfigure-2.1.2.RELEASE.jar包下能找到集合中的数据
以上就是Spring Boot的启动原理了。