springboot出现的原因:
ssm配置文件太过于复杂,需要配置文件编写,进行bean的装配,而springboot的出现,大大简化的开发的流程,所以spring boot的核心就在于自动装配,所以学习springboot一定要明白自动装配的原理,正是有了自动装配这个方面,所以一定要遵循约定大于配置的原则
创建maven项目(使用idea),使用官方的模板
其pom文件中的都是starter(启动器)
这里面有parent标签,表示这个pom文件为子项目的pom文件,点入之后,则发现其中之前的ssm文件过滤的配置和java版本和编译器的配置等等还有其他包的配置
其中这里面又存在着一个parent标签
点入后:发现里面存放着所有的jar包的版本的管理
pom.xml:
- spring-boot-dependencies:springboot的核心工程在父工程之中
- 我们在写或者引入一些springBoot依赖的时候,不需要指定其版本,因为有版本仓库
启动器:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- 启动器说白了就是Springboot的启动场景
- 比如spring-boot-starter-web,他就会帮我们导入web环境所有的依赖
- springboot会将所有的功能场景,都变成一个个的启动器,使用时只需要显式装配即可(找到对应的启动器即可)
主程序
@SpringBootConfiguration: springboot的配置
@Configuration: spring配置类
@Component: 说明这也是一个spring的组件
@EnableAutoConfiguration: 自动配置
@AutoConfigurationPackage: 自动配置包
@Import({Registrar.class}):导入自动配置包的注册器
@Import({AutoConfigurationImportSelector.class}):自动配置导入选择包(选择具体的已导入的starter进行自动装配)
AutoConfigurationImportSelector类中有核心的方法,获取所有的配置:
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
- 获取候选的配置(getCandidateConfigurations)
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
//通过加载器去加载所有的
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
查找标注了EnableAutoConfigration.class的所有的java文件:
实质上就是找到了SpringBootApplication的所有文件
而SpringBootApplication又在springboot启动类中
则这个过程就完成了:启动类下所使用的资源才进行导入
- META-INF/spring.factories : 自动装配的核心配置文件
紧接着上面的获取候选配置的方法(进一步解析)
这个就是排序
自动装配的流程图:
自动装配具体流程:
-
在pom文件中引入相应的starter
-
创建springboot的主入口文件,一定要有@SpringApplication注解:表示为springboot的主入口文件
-
进入SpringApplication的原文件,有三个注解@SpringBootConfiguration, @EnableAutoConfiguration以及@ComponentScan注解:
- @SpringBootConfiguration注解:深层实际上是一个组件,可被IOC容器扫描进去
- @ComponentScan注解:用于与主程序入口的同级的包进行相应的扫描,加入IOC容器中
- @EnableAutoConfiguration:自动装配的注解
-
点入EnableAutoConfiguration源文件:发现有两个注解:
- @AutoConfigurationPackage(自动扫描包配置)
- 里面含有:@Import(AutoConfigurationPackages.Registrar.class)
- AutoConfigurationPackages.Registrar这个类:主要用于对ComponentScan扫描到的包进行注册
- 里面含有:@Import(AutoConfigurationPackages.Registrar.class)
- @Import(AutoConfigurationImportSelector.class) (导入自动装配导入选择器)
- 自动装配导入选择器,里面存放着选择的具体方法:{getAutoConfigurationEntry(), getCandidateConfigurations() }
- getAutoConfigurationEntry():获得自动装配的实体类,在这里面调用了getCandidateConfigurations()方法
- getCandidateConfigurations()进行拿到候选的自动装配的配置类
- 这其中的所有的自动装配的配置存放在:META-INF/spring.factories当中
- 展开说明getCandidateConfigurations()方法:
- 这里的getSpringFactoriesLoaderFactoryClass()方法
返回的就是我们最开始看的启动自动导入配置文件的注解类;EnableAutoConfiguration - 里面调用了loadFactoryNames()方法
- loadFactoryNames()中又调用了loadSpringFactories()方法:
- 这里面加载了项目的配置和系统的配置
classLoader.getResources(“META-INF/spring.factories”) : ClassLoader.getSystemResources(“META-INF/spring.factories”); - 通过getResources和getSystemResources获得自动装配的相应的配置
并且遍历了这些资源中所有的元素(自动配置),然后封装成Properties供我们使用
- 这里面加载了项目的配置和系统的配置
- 这里的getSpringFactoriesLoaderFactoryClass()方法
- 自动装配导入选择器,里面存放着选择的具体方法:{getAutoConfigurationEntry(), getCandidateConfigurations() }
- @AutoConfigurationPackage(自动扫描包配置)
-
不是所有的自动装配的配置都封装成了Properties对象(配置对象),因为在spring.factories中的配置类中,所有的自动装配的实现类都实现了@@ConditionalOnXXX注解,必须又相应的starter才能对其进行自动装配
总结:
- springboot在启动的时候,从类路径下/META-INFl spring.factories获取指定的值;
- 将这些自动配置的类导入容器,自动配置就会生效,帮我进行自动配置!
- 以前我们需要自动配置的东西,现在springboot帮我们做了!
- 整个javaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure-2.2.0.RELEASE.jar这个包下
- 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器;
- 容器中也会存在非常多的xxxAutoConfiguration的文件(@Bean),就是这些类给容器中导入了这个场景需要的所有组件;并自动配置 与之前的JavaConfig一样@Configuration
- 有了自动配置类,免去了我们自动编写配置文件的工作
SpringApplication:
这个类主要做了以下四件事情(执行run方法):
-
推断应用的类型是普通的项目还是Web项目
-
查找并加载所有可用初始化器 , 设置到initializers属性中
-
找出所有的应用程序监听器,设置到listeners属性中
-
推断并设置main方法的定义类,找到运行的主类