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容器相关的启动 一.不 ...
随机推荐
- 吴裕雄--天生自然python编程:pycharm常用快捷键问题
最近在使用pycharm的时候发现不能正常使用ctrl+c/v进行复制粘贴,也无法使用tab键对大段代码进行整体缩进.后来发现是因为安装了vim插件的问题,在setting里找到vim插件,取消勾选即 ...
- SpringBoot + JPA + mariadb
SpringBoot + JPA + MariaDB 源码:https://github.com/ldl326308/LiveGreen-SpringBoot.git JPA持久层方法名命名规则:
- js数组中重复的对象去重
var arr = [{ "name": "ZYTX", "age": "Y13xG_4wQnOWK1QwJLgg11d0pS4h ...
- yii框架通过控制台命令创建定时任务
假设Yii项目路径为 /home/apps 1. 创建文件 /home/apps/web/protected/commands/console.php $yii = '/home/apps/frame ...
- Mybatis调用存储过程报错
Mybatis调用存储过程 贴码 123456 Error querying database. Cause: java.sql.SQLException: User does not have ac ...
- PyQt5之音乐播放器
按照自己思路简单写了个桌面播放器,只有自己喜欢的歌.使用QtDesigner设计的ui界面,功能简单,还有很多bug@~@,代码奉上: music_button.ui使用扩展工具pyuic5生成了mu ...
- 浅谈C# Dictionary实现原理
使用C#已经有好多年头了,然后突然有一天被问到C#Dictionary的基本实现,这让我反思到我一直处于拿来主义,能用就好,根本没有去考虑和学习一些底层架构,想想令人头皮发麻.下面开始学习一些我平时用 ...
- JavaScript实现栈结构(Stack)
JavaScript实现栈结构(Stack) 一.前言 1.1.什么是数据结构? 数据结构就是在计算机中,存储和组织数据的方式. 例如:图书管理,怎样摆放图书才能既能放很多书,也方便取? 主要需要考虑 ...
- 端口占用的一种形式 Failed to initialize end point associated with ProtocolHandler ["ajp-bio-8090"] java.net.BindException: Address already in use: JVM_Bind <null>:8090
严重: Failed to initialize end point associated with ProtocolHandler ["ajp-bio-8090"]java.ne ...
- 简单说 JavaScript中的事件委托(下)
说明 上次我们说了一些,关于 JavaScript中事件委托的 基础知识,这次我们继续来看. 解释 先来一段代码 <!doctype html> <html lang="e ...