SpringBoot源码分析(一)@SpringBootApplication解析
@SpringBootApplication解析
一、三层注解
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
二、@ComponentScan
1.相当于 xml 配置文件中的context:component-scan,
2.ComponentScan 默认会扫描当前类所在 package 下的的所有加了相关注解标识的类到 IoC 容器中
3.主要作用就是扫描指定路径下的标识了需要装配的类,自动装配到 spring 的 Ioc 容器中。标识的形式主要是: @Component 、@Repository、 @Service、 @Controller 这类的注解标识的类。
4.就是这个东西扫描我们自己写的Bean
三、@SpringBootConfiguration
源码打开本质是个@Configuration,标明是配置类。(后面run方法会把自己传进去,本身其它注解才失效)
四、@EnableAutoConfiguration
是由两个注解形成:
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
再打开@AutoConfigurationPackage源码:
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
}
总结:@EnableAutoConfiguration 等于
= @Import(AutoConfigurationPackages.Registrar.class)+@Import(AutoConfigurationImportSelector.class)
4.1 @Import
导入一个类到IOC容器中
4.2 AutoConfigurationPackages.Registrar
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata,
BeanDefinitionRegistry registry) {
register(registry, new PackageImport(metadata).getPackageName());
}
@Override
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new PackageImport(metadata));
}
}
其中registerBeanDefinitions方法,是为了注册bean==AutoConfigurationPackages类的,这个类保存了我们包扫描路径(com.xiaomi.项目名 这种,通过sb启动类Class信息拿到的),类注释说是 “用来存储自动配置包供以后的相关类使用(比如给JPA entity扫描器用来扫描开发人员通过注解@Entity定义的entity类)”
4.3 AutoConfigurationImportSelector
基于 ImportSelector 来实现基于动态 bean 的加载功能。 ImportSelector 接口的selectImports方法 返回的数组(类的全类名)都会被纳入到spring 容器中。
比较重要的是实现自DeferredImportSelector接口的方法selectImports
public 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方法里,一步步追查下去会发现在是在加载classpath路径下的META-INF/spring.factories文件里的类(SpringFactoriesLoader类的工作内容),这样是可扩展的,每个人都可以自己加这个文件自动装配。
剩余的代码就是 判断spring.factories文件里的类是否应该加载(有的设置了条件ConditionalOn)、去除重复的、冲突的等等 getAutoConfigurationEntry剩余代码如下:
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
4.4 SpringFactoriesLoader
spring.factories文件示例:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
这是mybatis对springboot自动装配的spring.factories,这样的话,通过这个文件就可以启动这个mybatis自动装配类MybatisAutoConfiguration了,不需要任何其它操作
SpringBoot源码分析(一)@SpringBootApplication解析的更多相关文章
- SpringBoot源码分析之SpringBoot的启动过程
SpringBoot源码分析之SpringBoot的启动过程 发表于 2017-04-30 | 分类于 springboot | 0 Comments | 阅读次数 SpringB ...
- 从SpringBoot源码分析 配置文件的加载原理和优先级
本文从SpringBoot源码分析 配置文件的加载原理和配置文件的优先级 跟入源码之前,先提一个问题: SpringBoot 既可以加载指定目录下的配置文件获取配置项,也可以通过启动参数( ...
- jQuery 2.0.3 源码分析Sizzle引擎解析原理
jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + ...
- springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)
之前两篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)和springMVC源码解析--HandlerMethodArgumentResol ...
- MyBatis 源码分析 - 映射文件解析过程
1.简介 在上一篇文章中,我详细分析了 MyBatis 配置文件的解析过程.由于上一篇文章的篇幅比较大,加之映射文件解析过程也比较复杂的原因.所以我将映射文件解析过程的分析内容从上一篇文章中抽取出来, ...
- Springboot源码分析之项目结构
Springboot源码分析之项目结构 摘要: 无论是从IDEA还是其他的SDS开发工具亦或是https://start.spring.io/ 进行解压,我们都会得到同样的一个pom.xml文件 4. ...
- springboot源码分析-SpringApplication
SpringApplication SpringApplication类提供了一种方便的方法来引导从main()方法启动的Spring应用程序 SpringBoot 包扫描注解源码分析 @Spring ...
- Springboot源码分析之jar探秘
摘要: 利用IDEA等工具打包会出现springboot-0.0.1-SNAPSHOT.jar,springboot-0.0.1-SNAPSHOT.jar.original,前面说过它们之间的关系了, ...
- Springboot源码分析之事务拦截和管理
摘要: 在springboot的自动装配事务里面,InfrastructureAdvisorAutoProxyCreator ,TransactionInterceptor,PlatformTrans ...
- SpringBoot源码分析(二)启动原理
Springboot的jar启动方式,是通过IOC容器启动 带动了Web容器的启动 而Springboot的war启动方式,是通过Web容器(如Tomcat)的启动 带动了IOC容器相关的启动 一.不 ...
随机推荐
- unittest(8)- 学习ddt
import unittest from ddt import ddt, data, unpack """ 1.正常情况下,测试函数(即测试用例)中不可以传参,如果要使用 ...
- flutter实践 - plsy
项目背景 项目需要从钉钉微应用跳转 WPS 打开 word 文档,但是 WPS 只提供了 StartActivity 方式携带参数跳转应用,deeplink 只能打开应用,而钉钉微应用只支持 deep ...
- legend图例
import matplotlib.pyplot as plt import numpy as np x=np.linspace(-3,3,50) y1=x*2+1 y2=x**2 plt.plot( ...
- Welcome to Erhan Blog
"Yeah It's on. " 前言 Erhan 的 Blog 就这么开通了. 跳过废话,直接看技术实现 2018 年,Hux 总算有个地方可以好好写点东西了. 作为一个程序员, ...
- PHP实现读取一个1G的文件大小
需求如下: 现有一个1G左右的日志文件,大约有500多万行, 用php返回最后几行的内容. 1. 直接采用file函数来操作 or file_get_content() 肯定报内存溢出注: 由于 fi ...
- 从游戏到汽车 “明星IP”的发财轨迹
"明星IP"的发财轨迹" title="从游戏到汽车 "明星IP"的发财轨迹"> 移动互联网时代的开启,不仅彻底重构了大众生 ...
- LeetCode~移除元素(简单)
移除元素(简单) 1. 题目描述 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使 ...
- 我去,你写的 switch 语句也太老土了吧
昨天早上通过远程的方式 review 了两名新来同事的代码,大部分代码都写得很漂亮,严谨的同时注释也很到位,这令我非常满意.但当我看到他们当中有一个人写的 switch 语句时,还是忍不住破口大骂:& ...
- SpringBoot图文教程9—SpringBoot 导入导出 Excel 「Apache Poi」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...
- 奉上简单的.Net后端开发模板
假定一个场景,开始做开发的你,领导走到你的面前说道:"小伙子,看了简历和最近的工作表现,很不错,现在交给一个任务,开发一个简单的CMS后端接口吧,前端有人配合你",当时你内心读白: ...