在springBoot中,我们不需要做任何的配置,可以直接编写业务层面的代码,原因就是springBoot帮我们配置好了所有的环境。
下面以一个简单的springboot项目进行分析
项目代码
springBoot主程序
@SpringBootApplication public class HelloApplication { public static void main(String[] args) { SpringApplication.run(HelloApplication.class, args); } }
pom文件的部分代码
org.springframework.boot spring-boot-starter-parent2.5.6 org.springframework.boot spring-boot-starter-web
先来分析pom文件,每一个springBoot项目都会引入一个父项目,点击进入,发现里面还有一个父项目,spring-boot-dependencies,通过这个名字可知,这个项目跟依赖有关。
org.springframework.boot spring-boot-dependencies2.5.6
再点击进入,发现springBoot为我们声明了几乎所有开发中依赖的版本号,我们在引入依赖时,无需声明版本号,由springBoot为我们自动选择版本号。
5.16.3 2.7.7 1.9.91 2.17.0 1.9.7 3.19.0 4.0.6 4.0.33.2.0 1.10.22 2.9.2 ......
接下来分析我们自己引入的依赖
官方文档:Starters 是一组方便的依赖描述符,您可以将它们包含在您的应用程序中。您可以获得所需的所有 Spring 和相关技术的一站式服务,而无需搜索示例代码和复制粘贴加载的依赖项描述符。
org.springframework.boot spring-boot-starter-web
我们引入这个依赖,就相当于引入了所有跟web有关的依赖。
可以看出,引入了spring-webmvc,spring-web,tomcat,json,starter。
简单分析了一下pom文件,接下来的重点是,分析项目在运行的时候,如何将配置自动完成装配。
对springBoot的主程序进行分析,发现该类上标注的一个注解 @SpringBootApplication 从
名字可以看出,该注解指明这是一个SpringBoot的项目。
点击进入发现,该注解上还有以下两个注解,接下来逐个分析
@SpringBootConfiguration @EnableAutoConfiguration
根据名字可知,@springBootConfiguration 是跟配置有关。
再点击进入发现 @springBootConfiguration 下 有一个@Configuration注解,表明我们的主程序HelloApplication 类一个配置类。
接下来看第二个注解 @EnableAutoConfiguration,根据名字就能知道,这个注解的作用是,完成自动配置的类。
点击进入,发现该注解上有两个注解,我们逐个分析
@AutoConfigurationPackage @import({AutoConfigurationimportSelector.class})
@AutoConfigurationPackage 根据名字可以知道,自动配置包,指定了默认的包规则,该注解的作用是,自动扫描主程序 HelloApplication 类 所在包的所有包。
我们点击进去,看看是怎么样完成这个功能的
@import({Registrar.class})
此注解的作用是,将Registrat类加载进入容器中。
点击进入,看看该类的功能是什么。
发现一个方法,registerBeanDefinitions 注册定义的bean对象
public void registerBeanDefinitions(Annotationmetadata metadata, BeanDefinitionRegistry registry) { AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.Packageimports(metadata)). getPackageNames().toArray(new String[0])); }
Annotationmetadata metadata 注解类的元数据,即为主程序 HelloApplication 类 的元数据
断点调试,发现(new AutoConfigurationPackages.Packageimports(metadata)).getPackageNames()
这个表达式的值就是 HelloApplication 类所在的包。
将主程序类HelloApplication所在的包下的所有组件加入容器。
现在就把 @AutoConfigurationPackage 这个注解的作用分析完成。
@EnableAutoConfiguration 还引入了一个类 @import({AutoConfigurationimportSelector.class})
AutoConfigurationimportSelector 自动配置导入选择器。
点解进入该类,里面有一个方法selectimports ,选择导入
public String[] selectimports(Annotationmetadata annotationmetadata) { if (!this.isEnabled(annotationmetadata)) { return NO_importS; } else { AutoConfigurationimportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationmetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); } }
其中 这个getAutoConfigurationEntry方法,自动配置加载的方法。
在这个方法中,这一行语句,获得了要加载的所有配置的信息。
Listconfigurations = this.getCandidateConfigurations (annotationmetadata, attributes);
进入getCandidateConfigurations 这个方法
protected ListgetCandidateConfigurations(Annotationmetadata metadata, AnnotationAttributes attributes) { List 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; }
在 SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()); 完成了加载。
点击进入 SpringFactoriesLoader 类中,发现
public static final String FACTORIES_RESOURCE_LOCATION = "meta-INF/spring.factories";
FACTORIES_RESOURCE_LOCATION 工厂的文件路径。也就是加载配置文件的路径。
springBoot 从 meta-INF/spring.factories 这个文件中读取要加载的配置文件信息。
也就是下面这个包下面的这个文件。
打开文件发现 ,文件中有所有的要配置的信息。
当然,也不是所有的配置类都要加载。
每个自动配置类根据条件进行加载。
按照条件装配规则(@Conditional),最终会按需配置。。。。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)