SpringBoot -- 自动化装配源码

news/2024/11/16 8:15:49/

自动化装配源码

      • @EnableAutoConfiguration 注解,开启自动配置的核心注解
        • @AutoConfigurationPackage 注解
      • AutoConfigurationImportSelector 类
        • getAutoConfigurationEntry 方法
        • getCandidateConfigurations 方法
      • SpringFactoriesLoader

在这里插入图片描述

@EnableAutoConfiguration 注解,开启自动配置的核心注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {...
}

@EnableAutoConfiguration 包含了@AutoConfigurationPackage 注解和 @Import(AutoConfigurationImportSelector.class) 注解。

在这里插入图片描述

@AutoConfigurationPackage 注解

在这里插入图片描述

@AutoConfigurationPackage 通过 AutoConfigurationPackages.Registrar 将应用主类所在包及其子包下的所有组件扫描到Spring容器中。
在这里插入图片描述
在这里插入图片描述
重写这个方法就可以把包注册到spring 容器里面
在这里插入图片描述

有4个接口和一个注解都可以把对应类型放到容器里面,上文从源码来看是约定了一个接口,具体如何注册,看实现方式 AutoConfigurationPackages.register(registry, (new PackageImport(metadata)).getPackageName());
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
放到了定义map中
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/31769717ef5449fd915b9a479b15ad08.png
放到bean工厂,容器启动加载进去指的一说的是这个类,核心类 DefaultListableBeanFactory

从图中可以看到实现了 BeanFactory 接口和 ListableBeanFactory、ConfigurableListableBeanFactory、AutowireCapableBeanFactory 等多个接口。这个类是 Spring 容器的默认实现之一,是一个全功能的 Spring Bean 工厂,提供对 Bean 的完整管理,包括 Bean 的创建、定义、解析依赖、配置等功能

在这里插入图片描述

AutoConfigurationImportSelector 类

AutoConfigurationImportSelector 主要作用是收集和加载所有的自动配置类。
在这里插入图片描述


public class AutoConfigurationImportSelector extends ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}
}
getAutoConfigurationEntry 方法

在这里插入图片描述

getAutoConfigurationEntry 方法用于获取所有的自动配置类:

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

getCandidateConfigurations 方法从 spring.factories 文件中加载所有的候选配置类:
在这里插入图片描述

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {List<String> 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;
}

SpringFactoriesLoader

在这里插入图片描述
在这里插入图片描述

SpringFactoriesLoader.loadFactoryNames 方法会读取 META-INF/spring.factories 文件中的配置,获取所有自动配置类的全限定名。

public abstract class SpringFactoriesLoader {private static final Map<ClassLoader, Map<String, List<String>>> cache = new ConcurrentReferenceHashMap<>();public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {String factoryClassName = factoryClass.getName();return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());}private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);if (result != null) {return result;} else {try {Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");// 下面先别管MultiValueMap<String, String> result = new LinkedMultiValueMap();while(urls.hasMoreElements()) {URL url = (URL)urls.nextElement();UrlResource resource = new UrlResource(url);Properties properties = PropertiesLoaderUtils.loadProperties(resource);Iterator var6 = properties.entrySet().iterator();while(var6.hasNext()) {Map.Entry<?, ?> entry = (Map.Entry)var6.next();String factoryClassName = ((String)entry.getKey()).trim();String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());int var10 = var9.length;for(int var11 = 0; var11 < var10; ++var11) {String factoryName = var9[var11];result.add(factoryClassName, factoryName.trim());}}}cache.put(classLoader, result);return result;} catch (IOException var13) {throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);}}}}

在这里插入图片描述
基本就结束了


http://www.ppmy.cn/news/1547401.html

相关文章

Rust 语言学习笔记(五)

终于来到了 Rust 的精髓所在了&#xff0c;那就是使之不依赖于垃圾回收又能保障内存安全且高效运行的所有权系统(Ownership System)。想要用 Rust 做一个稍显规模项目必定绕不过它&#xff0c;所有权系统包括所有权(Ownership), 借用(Borrowing), 生命周期(Lifetimes)。 以下概…

【教程】Ubuntu设置alacritty为默认终端

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 背景介绍 设置教程 注意事项 背景介绍 alacritty是一个开源的终端&#xff0c;比默认的xterm更好看&#xff0c;甚至编辑文本时候还会代码高亮…

使用 Vue 和 ECharts 创建交互式图表

使用 Vue 和 ECharts 创建交互式图表 引言 在现代 Web 应用中&#xff0c;数据可视化是一个重要的组成部分。它不仅能够帮助用户更好地理解复杂的数据&#xff0c;还能提升用户体验。 技术背景 Vue.js Vue.js 是一个渐进式 JavaScript 框架&#xff0c;用于构建用户界面。…

面试经典 150 题:20、2、228

20. 有效的括号 参考代码 #include <stack>class Solution { public:bool isValid(string s) {if(s.size() < 2){ //特判&#xff1a;空字符串和一个字符的情况return false;}bool flag true;stack<char> st; //栈for(int i0; i<s.size(); i){if(s[i] ( |…

免押租赁系统的优势与应用前景分析

内容概要 免押租赁系统是一种新兴的租赁形式&#xff0c;它利用了信用大数据与区块链技术的优势&#xff0c;帮助用户摆脱了传统租赁中常见的押金烦恼。通过这种方式&#xff0c;用户不仅可以体验到更低的租用门槛&#xff0c;还能享受到更顺畅的交易过程。用户只需提供基本的…

Linux网络——网络初识

目录 1. 认识协议 2. 协议的分层 3. OSI 七层模型 && TCP/IP 五层(四层)模型 4. 网络传输的基本流程 5. 以太网的通信原理 6. 数据的跨网络传播 7. 认识 IP 地址 ① IP 是什么 ② IP 与 MAC 的关系 ③ 为什么需要 IP 在谈及网络之前&#xff0c;我们要先对学…

React Native 全栈开发实战班 - 第四部分:用户界面进阶之动画效果实现

在移动应用中&#xff0c;动画效果 是提升用户体验的重要手段。合理的动画设计可以增强应用的交互性、流畅性和视觉吸引力。React Native 提供了多种实现动画的方式&#xff0c;包括内置的 Animated API、LayoutAnimation 以及第三方库&#xff08;如 react-native-reanimated&…

酒店行业数据仓库

重要名词&#xff1a; PMS&#xff1a;酒店管理系统CRS&#xff1a;中央预定系统客户&#xff1a;可以分为会员、散客&#xff08;自行到店入住&#xff09;、协议&#xff08;与酒店长期合作&#xff0c;内部价&#xff09;、中介预定&#xff1a;可以分为线上预定、线下预定…