IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringBoot的自动配置原理 -> 正文阅读

[Java知识库]SpringBoot的自动配置原理

原理

@SpringBootApplication

在springboot项目的启动类中,都会存在一个@SpringBootApplication注解,进入这个注解中看一看。
在这里插入图片描述
可以发现,在这个注解中又包含了@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan注解,大概解释一下这写注解的作用:

  • @SpringBootConfiguration:这个注解里面又包含了@Configuration注解,其实主要作用就是将当前类声明为一个配置类,可以在类中注入一些Bean;
  • @EnableAutoConfiguration这个注解是实现springboot自动装配的核心注解,在下面会来说这个注解;
  • @ComponentScan:组件扫描,默认会扫描启动类包下的所有类,你也可以使用excludeFilters属性来排除一些类的扫描,如上图所示。

@EnableAutoConfiguration

进入到这个注解中,其核心就是这个**@Import注解。
在这里插入图片描述
可以发现这里通过@Import注解导入了一个
AutoConfigurationImportSelector类。
在这里插入图片描述
并且,这个类实现了
ImportSelector**接口的selectImports方法。
在这里插入图片描述
在这里插入图片描述

这里必须要补充一下@Import注解的用法之一

当@Import了某一个类时,并且这个类实现了ImportSelector中的selectImports方法,那么实现方法selectImports的返回的全类名就会被注入的容器中。
比如:

自定义了一个类实现ImportSelector,并重写了selectImports方法,可以看到该访问返回了一个类的全类名。

public class MyImportClass implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.sunao.entity.User"};	// 这里也可以有多个
    }
}

那么,接下来通过@Import(MyImportClass.class)注解,配置类加载时就会将User对象注入到容器中。

其实springboot的自动配置主要就是先去读取spring.factories配置文件中配置类的全类名,然后再通过上面这种方式将他们加载到容器中的。

我们可以下面的依赖包下找到spring.factories配置文件。
在这里插入图片描述在这里插入图片描述

其实不仅仅是spring-boot-autoconfigure包下会有这个文件,很多第三方依赖也会自己定义spring.factories文件,它们都会被启动类扫描到。
在这里插入图片描述

这样一看,我们完全可以自己写一个starter,实现自动装配功能,在下面会提到。

selectImports方法

@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
	if (!isEnabled(annotationMetadata)) {	// 判断是否开启了自动配置功能开关
		return NO_IMPORTS;
	}
	// 获取需要加载到容器中的配置类信息
	AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
	// 将这些配置类的全类名作为返回值返回 这样就会将这些配置类加载到容器中
	return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

再来看一下getAutoConfigurationEntry(annotationMetadata)这个方法具体是怎么实现的。

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {	// 
	if (!isEnabled(annotationMetadata)) {	// 判断是否开启了自动配置功能开关
		return EMPTY_ENTRY;
	}
	// 获取到注解中定义的一些属性
	AnnotationAttributes attributes = getAttributes(annotationMetadata);
	// 内部调用了SpringFactoriesLoader.loadFactoryNames方法 获取spring.factories文件中定义的自动配置类
	List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
	// 通过LinkedHashSet去掉重复的配置类 ---> 去重
	configurations = removeDuplicates(configurations);
	// 获取我们指定需要排除的类 比如:@SpringBootApplication(excludeName = "xxx", exclude = Xxx.class)
	Set<String> exclusions = getExclusions(annotationMetadata, attributes);
	checkExcludedClasses(configurations, exclusions);
	configurations.removeAll(exclusions);
	// 根据条件过滤掉一些不满足加载条件的配置类
	configurations = getConfigurationClassFilter().filter(configurations);
	fireAutoConfigurationImportEvents(configurations, exclusions);
	return new AutoConfigurationEntry(configurations, exclusions);
}

getAttributes(annotationMetadata)

在这里插入图片描述

getCandidateConfigurations(annotationMetadata, attributes)

在这里插入图片描述

其内部主要就是调用了SpringFactoriesLoader.loadFactoryNames方法

在这里插入图片描述

在调用完getConfigurationClassFilter().filter(configurations)方法之后,可以发现过滤了很多配置类,从137 —> 27了

在这里插入图片描述

这个方法主要就是用来过滤掉一些不需要加载的类,比如我们很多时候会在配置类上添加该配置类加载的条件,当不满足这些条件时,就不需要去加载该类

在这里插入图片描述

这里面试可能会问你:spring.factories中的配置类会全部被加载吗?
当然不是,会通过getConfigurationClassFilter().filter(configurations)这个方法过滤掉很多不需要加载的类。

最后一步,new AutoConfigurationEntry(configurations, exclusions)

在这里插入图片描述

通过这些全类名,将他们加载到容器中

在这里插入图片描述

自定义一个starter

在了解了上述的原理之后,你想自己写一个starter实现自动配置就会变得非常非常简单。

步骤:

  1. 创建一个springboot项目:my-auto-config-boot-starter,并且添加一个基本依赖即可
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter</artifactId>
       </dependency>
    
  2. 自定义一个自动配置类
    @Configuration
    public class MyThreadPoolAutoConfiguration {
    
        @Bean
        @ConditionalOnClass(ThreadPoolExecutor.class)
        public ThreadPoolExecutor myTreadPool() {
            return new ThreadPoolExecutor(520, 1314, 2000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
        }
    
    }
    
  3. 在resources路径下创建spring.factories
    在这里插入图片描述

表示在springboot启动时,我们要将MyThreadPoolAutoConfiguration注入到容器中,实现自动配置;

  1. 在创建一个springboot项目,导入我们刚刚项目的依赖
    <!-- 导入我们自己定义的配置类starter依赖 -->
    <dependency>
        <groupId>com.sunao</groupId>
        <artifactId>my-auto-config-boot-starter</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
    
  2. 启动测试
    @Slf4j
    @SpringBootApplication
    public class SpringbootDemo01Application {
    
        public static void main(String[] args) {
            ConfigurableApplicationContext run = SpringApplication.run(SpringbootDemo01Application.class, args);
            ThreadPoolExecutor myThreadPool = run.getBean(ThreadPoolExecutor.class);
            log.info("core pool size: {}, max pool size: {}", myThreadPool.getCorePoolSize(), myThreadPool.getMaximumPoolSize());
        }
    
    }
    
    在这里插入图片描述
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 20:27:04  更:2022-10-08 20:29:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 -2025/3/10 15:59:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码