SpringBoot自动配置原理源码级别分析
SpringBoot自动配置原理
前言
后面还会讲到SpringBoot自动配置原理,会主要讲解@EnableAutoConfiguratuon注解帮助我们做了什么事情,是如何自动把自动配置类扫描到容器中的,建议看完这篇后,两篇配合使用,传送门
package com.staticzz.springboot_quick;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
**@SpringBootApplication注解为核心注解
**
**/
@SpringBootApplication
public class SpringbootQuickApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootQuickApplication.class, args);
}
}
2.1.1 SpringBootApplication注解作用
@SpringBootApplication 标注在某一个类上,就说明这个类为SpringBoot应用的主配置类,SpringBoot就应该运行这个类的main方法来启动Springboot应用
以前我们开发一个SSM项目,需要利用配置文件进行相关配置,而SpingBoot利用了配置类进行自动配置,
这里配置类等同于配置文件,SpringBoot并且开启了自动配置,以前我们需要手动配置的东西
这里SpringBoot帮我们进行了自动配置
PS: 自动配置原理也是SpringBoot的精髓所在
package com.staticzz.springboot_quick;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
@SpringBootApplication注解标注在某一个类上,
就说明这个类为SpringBoot应用的主程序类
SpringBoot就应该运行这个类的main方法来启动Springboot应用
**/
@SpringBootApplication
public class SpringbootQuickApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootQuickApplication.class, args);
}
}
那 @SpringBootApplication 这个注解与自动配置又有什么关系呢?
接下来我们Ctrl+左键,进入到这个注解中来查看 @SpringBootApplication 这个注解里到底配置了什么?我们先来进入到@SpringBootApplication这个注解中,看看它底层调用了什么注解
动图演示:
我们观察到 @SpringBootApplication注解 继承了 @SpringBootConfiguration注解 ,而 @SpringBootConfiguration注解 又继承了Spring底层的注解 @Configuration注解 , 凡是标注该注解的类都是配置类
那现在也只是知道了 @SpringBootApplication注解 一层一层的实现了Spring底层的 @Configuration注解 ,被标注后称为配置类!那说了这篇文章讲的是SpringBoot的自动配置?配置有了,自动呢?
我没有骗人哦!确实是有自动配置的!而且SpringBoot也确确实实帮我们做了自动配置
先上一张动态演示图,瞧瞧
第一步 ctrl+右键 进入了 @EnableAutoConfiguration 这个注解
@SuppressWarnings("deprecation")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
/**
**这个注解为自动导包的注解
**/
@AutoConfigurationPackage
/**
**这个为开启自动配置选择器的注解
**/
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
/**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
Class<?>[] exclude() default {};
/**
* Exclude specific auto-configuration class names such that they will never be
* applied.
* @return the class names to exclude
* @since 1.3.0
*/
String[] excludeName() default {};
}
有没有发现我在这动态演示中,重点高亮了两个注解
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
这两个注解分别是什么意思 废话不多说 下面看!
@AutoConfigurationPackage 自动扫描包
@Import(EnableAutoConfigurationImportSelector.class) 导入自动配置类选择器组件
来看源码分析
@AutoConfigurationPackage
源码展示:
/**
* {@link ImportBeanDefinitionRegistrar} to store the base package from the importing
* configuration.
*/
@Order(Ordered.HIGHEST_PRECEDENCE)
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
//这个方法为SpringBoot帮助我们自动扫描包获取获取包名并进行注册
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata,
BeanDefinitionRegistry registry) {
register(registry, new PackageImport(metadata).getPackageName());
}
@Override
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.<Object>singleton(new PackageImport(metadata));
}
}
动态展示 自动扫描包
注意观察动图中我高亮的部分
结论: SpringBoot在启动时,会自动扫描主程序类所在的包下的所有子包
来看源码分析
@Import(EnableAutoConfigurationImportSelector.class)
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
try {
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
//获取到注解元数据
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//获取到配置类封装为一个list数据
List<String> configurations = getCandidateConfigurations(annotationMetadata,
attributes);
configurations = removeDuplicates(configurations);
configurations = sort(configurations, autoConfigurationMetadata);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
//返回给容器
return configurations.toArray(new String[configurations.size()]);
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
@Import(EnableAutoConfigurationImportSelector.class) 这个注解的作用选择自动配置类并扫描进容器中,
动态展示 导入自动配置类选择器组件
总结: SpringBoot给容器中导入非常多的自动配置类(xxxAutoConfiguration),就是给容器中导入场景所需要的所有组件并自动配置好这些组件
SpringBoot自动配置原理源码级别分析的更多相关文章
- Spring Boot自动装配原理源码分析
1.环境准备 使用IDEA Spring Initializr快速创建一个Spring Boot项目 添加一个Controller类 @RestController public class Hell ...
- 助力SpringBoot自动配置的条件注解ConditionalOnXXX分析--SpringBoot源码(三)
注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 前言 本篇接 如何分析SpringBoot源码模块及结构?--SpringBoot源码(二) 上一篇分析了SpringBoo ...
- SpringBoot自动配置的源码解析
首先,写源码分析真的很花时间,所以希望大家转的时候也请注明一下,Thanks♪(・ω・)ノ SpringBoot最大的好处就是对于很多框架都默认的配置,让我们开发的时候不必为了大一堆的配置文件头疼,关 ...
- Java ArrayList底层实现原理源码详细分析Jdk8
简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用 ...
- SpringBoot自动配置源码调试
之前对SpringBoot的自动配置原理进行了较为详细的介绍(https://www.cnblogs.com/stm32stm32/p/10560933.html),接下来就对自动配置进行源码调试,探 ...
- 源码学习系列之SpringBoot自动配置(篇二)
源码学习系列之SpringBoot自动配置(篇二)之HttpEncodingAutoConfiguration 源码分析 继上一篇博客源码学习系列之SpringBoot自动配置(篇一)之后,本博客继续 ...
- springboot自动配置源码解析
springboot版本:2.1.6.RELEASE SpringBoot 自动配置主要通过 @EnableAutoConfiguration, @Conditional, @EnableConfig ...
- 源码学习系列之SpringBoot自动配置(篇一)
源码学习系列之SpringBoot自动配置源码学习(篇一) ok,本博客尝试跟一下Springboot的自动配置源码,做一下笔记记录,自动配置是Springboot的一个很关键的特性,也容易被忽略的属 ...
- springboot自动配置国际化失效分析
最近在整理springBoot国际化时,发现国际化没有生效,通过报错提示在 MessageTag -> doEndTag处打断点 最后发现messageSource并不是ResourceBund ...
随机推荐
- 数理统计8:点估计的有效性、一致最小方差无偏估计(UMVUE)、零无偏估计法
在之前的学习中,主要基于充分统计量给出点估计,并且注重于点估计的无偏性与相合性.然而,仅有这两个性质是不足的,无偏性只能保证统计量的均值与待估参数一致,却无法控制统计量可能偏离待估参数的程度:相合性只 ...
- SpringCloud @RefreshScope标注的Bean在生命周期中怎么样的?
@RefreshScope 前言 该文章是由上一篇引申而来的,上一篇文章描述了Nacos是怎么触发配置刷新的,接着来写有关@RefreshScope的一些东西,都是由DEBUG而来 上一篇 文章概览 ...
- kubernetes生态--交付prometheus监控及grafana炫酷dashboard到k8s集群
由于docker容器的特殊性,传统的zabbix无法对k8s集群内的docker状态进行监控,所以需要使用prometheus来进行监控: 什么是Prometheus? Prometheus是由Sou ...
- Kubernets二进制安装(15)之安装部署coredns
在运维主机上(mfyxw50.mfyxw.com)准备Coredns镜像文件,以docker镜像文件的方式部署到Kubernetes集群中去. 1.下载coredns镜像 [root@mfyxw50 ...
- .NET Core项目自动化测试和代码覆盖率审查
这篇文章给大家分享一下,如何配置.NET Core项目自动化测试和代码覆盖率审查. 基本知识,请参考这里: https://docs.microsoft.com/en-us/dotnet/core/t ...
- CodeForces - 803C Maximal GCD 【构造】
You are given positive integer number n. You should create such strictly increasing sequence of k po ...
- 数据分析常用库(numpy,pandas,matplotlib,scipy)
概述 numpy numpy(numeric python)是 python 的一个开源数值计算库,主要用于数组和矩阵计算.底层是 C 语言,运行效率远高于纯 python 代码.numpy主要包含2 ...
- 对于kmp求next数组的理解
首先附上代码 1 void GetNext(char* p,int next[]) 2 { 3 int pLen = strlen(p); 4 next[0] = -1; 5 int k = -1; ...
- WSL2+Terminal+VScode配置调试
最近几天一直想找个方法把VMware虚拟机和远程连接工具MobaXterm这一组配合替换掉,因为每次开启虚拟机操作Ubuntu都需要占用很大的内存,而且要等好久好久才能开启!!!后面还要使用MobaX ...
- 如何重置电信悦 me 智能网关
如何重置电信悦 me 智能网关 重置电信网关密码 电信悦 me 智能网关密码忘记了怎么办? 首先,得要知道默认终端配置地址和默认终端配置密码. 可以从无线路由器背面标签得知. 如果不知道密码了,可以通 ...