栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot自动装配原理及过程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot自动装配原理及过程

一、何为自动装配?

试想一下,我们导入一些外部配置文件后,想要将这些配置文件引入到工程中使用,我们需要进行很多配置工作或者书写很多配置文件才能完成,废不废劲?麻不麻烦?

福音来到:Springboot的自动装配原理设计,很好的解决了这个问题,即Spring容器启动过后,一些自动装配类就会自动装配到IOC容器中,不需要我们手动注入,好开心!!!;

二、自动装配原理

1. SPI:是server provider interface 的简写,字面意思是服务发现接口,我理解就是第三方拓展API,他是java提出的,即开箱即用的思想。在spring的生态中已经运用得非常多,比如springMVC中官方推荐的去web.xml的方式,用一个onStart的方法就将dispatcherServlet到IOC的容器中,这也是利用了tomcat的SPI。在springBoot中,当我们加一个starter的包,spring将帮我们注入了一些类。你删掉包后,spring就不会注入。不会产生任何的影响,这就是SPI的思想,拆箱即用;

2. 分析注解

首先看一下流程图:

 从启动类出发:

@SpringBootApplication
public class Springboot04DataApplication {

    public static void main(String[] args) {
        SpringApplication.run(Springboot04DataApplication.class, args);
    }
}

@SpringBootApplication 为组合注解,点击进入会发现由以下三个注解组成:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

自动装配的秘密在 @EnableAutoConfiguration 注解,点击进入会发现由以下两注解组成:

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)

首先分析@AutoConfigurationPackage

该注解字面分析为自动配置包,也为组合注解,点击进入发现主要由以下注解组成:

@Import(AutoConfigurationPackages.Registrar.class)

@Import注解导入了导⼊了⼀个Registrar 的组件,这个注解的作用就是将主配置类(标注了@SpringBootAutoConfiguration的类)所在的包及子包里面的组件扫描到IOC容器中。所以默认情况下主配置类所在的包及其子包的组件会被自动加载到IOC容器中;

其次再分析@Import(AutoConfigurationImportSelector.class)

通过@Import注解导入AutoConfigurationImportSelector类,该类中selectimport方法会通过SpingFactoriesLoader得到大量的配置类,最后通过每个配置类自身的条件做出决策(是否生效),完成配置类的自动加载;

重点看一下selectimport方法:

public String[] selectImports(AnnotationMetadata annotationMetadata) {
	if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
	}
	AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
	return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		List configurations = getCandidateConfigurations(annotationMetadata, attributes);
		configurations = removeDuplicates(configurations);
		Set exclusions = getExclusions(annotationMetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);
		configurations = getConfigurationClassFilter().filter(configurations);
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}

protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
		List configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				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;
	}

主要做了三件事情:

1. 从classpath下获取META-INF/spring.factories这个文件下的信息;

2. 将上面获取的信息封装成Enumeration返回;

3. 遍历Enumeration,然后获取key为EnableAutoConfiguration下的所有值;

三、总结

整个过程:

位于META-INF目录下的spring.factortes文件存放相关组件的配置工厂类;@EnableAutoConfiguration核心配置注解里面有一个AutoConfigurationImportSelector(自动配置文件收集器),收集配置文件中的配置工厂类,然后SpringFactoriesLoader加载组件工程(抽象工厂模式)进行实例化,在spring上下文中生成bean,完成自动配置功能。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/868195.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号