0
点赞
收藏
分享

微信扫一扫

SpringBoot自动装配原理初探

覃榜言 2022-04-26 阅读 166
spring boot

pom.xml

写入依赖时不用写版本号核心依赖已经存在与父工程中

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.6.7</version>
</parent>

启动器

SpringBoot会将所有的功能场景,都变成启动器

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter</artifactId>
</dependency>

例如spring-boot-starter-webspring-boot-starter-log4j自动导入web、log4j环境的依赖

主程序(重点)

@SpringBootApplication
public class SpringbootWeeexApplication {
	public static void main(String[] args) {
		SpringApplication.run(SpringbootKuangApplication.class, args);
    }
}

@SpringBootApplication注解:

标注这个类是一个SpringBoot的应用
首先我们来看一下这个注解的源码,里面四个基本注解,两个扫描注解,这些可以暂时不管,其中还有这样两个核心注解:

@SpringBootConfiguration  //SpringBoot的配置类
@EnableAutoConfiguration  //自动配置
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)  //扫描当前主启动类同级的包

1. @SpringBootConfiguration
首先简单的看一下这个注解的源码

  • @SpringBootConfiguration:SpringBoot的配置类
    • @Configuration:Spring配置类
      • @Compoent :Spring组件

可以看出来,这些都是Spring中的注解,没有新的东西,表示了这是一个组件而已
其中还有一个注解是

2. @EnableAutoConfiguration
这是SpringBoot实现自动装配的重要注解!!
仍然先是看一下注解的源码

  • @EnableAutoConfiguration:
    • @AutoConfigurationPackage:
      • @Import({Registrar.class}):自动注册包
    • @Import({AutoConfigurationImportSelector.class}) 自动导包核心

@AutoConfigurationPackage就是自动注册了包
我们重点来看一下@Import({AutoConfigurationImportSelector.class})
AutoConfigurationImportSelector从名字可以看出,这是一个自动导入选择器
进入源码查看

//第一个方法为 选择导入
public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
        	// 首先加载元数据,在加载完元数据后进入方法AutoConfigurationImportSelector获得自动配置实体
        	// 跳转到下面的方法
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }


protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            // 获取候选的配置
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations = this.removeDuplicates(configurations);
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.getConfigurationClassFilter().filter(configurations);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
        }
    }


protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
	// loadFactoryNames获取了所有的加载配置名
	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;
}

以上几个方法主要是获取了所有的配置类
而这些配置又从哪儿来的呢?
我们可以进入loadFactoryNames()方法中看到调用了loadSpringFactories()方法

loadSpringFactories()方法有下面一行代码,可以看到是从META-INF/spring.factories文件中获取配置

Enumeration urls = classLoader.getResources("META-INF/spring.factories");

而这个文件在

这个文件中存在大量的自动配置,这是SpringBoot中已经存在的

注意

虽然已经加载了这个文件中的配置类,但是许多配置类并没有生效,需要导入对应的spring-boot-starter-xxx才生效
这是因为存在@ConditionalOnClass(),当判断条件成立才会去加载那个类

刚开始学习SpringBoot,许多理解可能并不到位,也只是当作自己一个记事本用,如果有错误,请多多指教、包涵~~~

举报

相关推荐

0 条评论