SpringBoot自动装配原理分析

SpringBoot自动装配原理分析,第1张

SpringBoot自动装配原理分析

在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-parent
  2.5.6
   



  org.springframework.boot
  spring-boot-starter-web

先来分析pom文件,每一个springBoot项目都会引入一个父项目,点击进入,发现里面还有一个父项目,spring-boot-dependencies,通过这个名字可知,这个项目跟依赖有关。


    org.springframework.boot
    spring-boot-dependencies
    2.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.3
3.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方法,自动配置加载的方法。
在这个方法中,这一行语句,获得了要加载的所有配置的信息。

 List configurations = this.getCandidateConfigurations
 (annotationmetadata, attributes);


进入getCandidateConfigurations 这个方法

protected List getCandidateConfigurations(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),最终会按需配置。。。。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5075507.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-16
下一篇 2022-11-16

发表评论

登录后才能评论

评论列表(0条)

保存