SpringBoot源码解析
1.@SpringBootApplication
springboot采用注解方式开发的,当创建了一个springboot项目时,在启动类上会有一个注解@SpringBootApplication,这个注解用来标识是一个springboot的项目,并且此类是启动类。
进入@SpringBootApplication,其源码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication { /**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
@AliasFor(annotation = EnableAutoConfiguration.class)
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
*/
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {}; /**
* Base packages to scan for annotated components. Use {@link #scanBasePackageClasses}
* for a type-safe alternative to String-based package names.
* @return base packages to scan
* @since 1.3.0
*/
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {}; /**
* Type-safe alternative to {@link #scanBasePackages} for specifying the packages to
* scan for annotated components. The package of each class specified will be scanned.
* <p>
* Consider creating a special no-op marker class or interface in each package that
* serves no purpose other than being referenced by this attribute.
* @return base packages to scan
* @since 1.3.0
*/
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {}; }
先看@Target:
2.一级注解
2.1@Target
作用是指定注解的使用范围。其源码如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
在这个注解里面就定义了一个枚举类型的数组,其枚举类型如下:
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
表示的意义见表格:
| 类型 | 说明 | 用法 |
| TYPE | 表明此注解只能用于接口、类上 |
@Target(ElementType.TYPE) |
| FIELD | 表明此注解只能用于字段上 | @Target(ElementType.FIELD) |
| METHOD | 表明此注解只能用于方法上 | @Target(ElementType.METHOD) |
| PARAMETER | 表明此注解只能用于方法参数上 | @Target(ElementType.PARAMETER) |
| CONSTRUCTOR | 表明此注解只能用于构造函数上 | @Target(ElementType.CONSTRUCTOR) |
| LOCAL_VARIABLE | 表明此注解只能用于局部变量上 | @Target(ElementType.LOCAL_VARIABLE) |
| ANNOTATION_TYPE | 表明此注解只能用于注解上 | @Target(ElementType.ANNOTATION_TYPE) |
| PACKAGE | 表明此注解只能用于包上 | @Target(ElementType.PACKAGE) |
| TYPE_PARAMETER | 表明此注解只能用于类型参数上 | @Target(ElementType.TYPE_PARAMETER) |
| TYPE_USE | 表明此注解只能用于任何类型上 | @Target(ElementType.TYPE_USE) |
再回到上面的源码,@Target(ElementType.TYPE)也就指定了注解只能用于接口、类上。
2.2.@Retention
作用是指定注解的保留位置。其源码如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
注解中定义了一个枚举,源码如下:
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
其中
SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃; CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期; RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在,即在运行时也存在。
那么源码中的注解就表示在运行时此注解也存在。
2.3@Documented
作用是指定自定义的注解是否能随着被定义的java文件生成到JavaDoc文档当中。那么源码中的注解就表示注解会生成到JavaDoc文档中。
2.4@Inherited
作用是只有用在类上时,会被子类继承此自定义的注解。也就是说当@Inherited注解加在某个类A上时,假如类B继承了A,则B也会带上该注解。那么源码中的注解就表示定义的注解被继承时子类也有父类的这些注解。
2.5@SpringBootConfiguration
其继承自@Configuration,表明当前类是配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到spring容器中,并且实例名就是方法名。那么源码中的注解就表示当前的注解是一个SpringBoot的配置类。
2.6@EnableAutoConfiguration
作用是开启允许自动配置,这样spring会帮我们自动配置。主要源码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
....
}
红色的注解在二级注解中介绍。
2.7@ComponentScan
作用是定义扫描的路径并从中找出标识了需要装配的类自动装配到spring的bean容器中,简单的说,就是把指定的类交给spring来管理。会被自动装配的注解包括@Controller、@Service、@Component、@Repository等等。那么源码中的注解就是扫描启动类所在的包以及下面的包。
3.二级注解
3.1@Import
作用是给容器中导入一个组件。那么源码中的注解作用是将所有需要导入的组件以全类名的方式返回并自动导入所有符合自动配置条件的Bean定义并加载到IOC容器。
3.2@AutoConfigurationPackage
作用是自动配置包,源码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage { }
@Import指定导入的组件由AutoConfigurationPackages.Registrar.class将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器。
Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作。
SpringBoot源码解析的更多相关文章
- 【spring-boot 源码解析】spring-boot 依赖管理梳理图
在文章 [spring-boot 源码解析]spring-boot 依赖管理 中,我梳理了 spring-boot-build.spring-boot-parent.spring-boot-depen ...
- SpringBoot源码解析系列文章汇总
相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的SpringBoot源码解析系列文章的汇总,当你使用SpringBoot不仅仅满足于基本使用时.或者出去面试被面试官虐了时.或者说想要深入了解一下 ...
- springboot源码解析-管中窥豹系列之总体结构(一)
一.简介 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之项目类型(二)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之Runner(三)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之Initializer(四)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之排序(五)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之aware(六)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之web服务器(七)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之BeanDefinition(八)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
随机推荐
- 在 .NET Core Logging中使用 Trace和TraceSource
本文介绍了在.NET Core中如何在组件设计中使用Trace和TraceSource. 在以下方面会提供一些帮助: 1.你已经为.NET Framework和.NET Core / .NET Sta ...
- 全网最硬核 JVM TLAB 分析(单篇版不包含额外加菜)
今天,又是干货满满的一天.这是全网最硬核 JVM 系列的开篇,首先从 TLAB 开始.由于文章很长,每个人阅读习惯不同,所以特此拆成单篇版和多篇版 全网最硬核 JVM TLAB 分析(单篇版不包含额外 ...
- Luogu T7468 I liked Matrix!
题目链接 题目背景 无 题目描述 在一个n*m 的矩阵A 的所有位置中随机填入0 或1,概率比为x : y.令B[i]=a[i][1]+a[i][2]+......+a[i][m],求min{B[i] ...
- poj 2653 线段相交裸题(解题报告)
#include<stdio.h> #include<math.h> const double eps=1e-8; int n; int cmp(double x) { if( ...
- hutool学习总结
1. 为什么要学习Hutool的使用 Hutool官网 中文写的已经很清楚了 Hutool是一款强力的工具类.封装了工作开发中一些常见的功能操作.避免重复造轮子,使用它大大提高的开发效率. 2. Hu ...
- js中for循环遍历的写法
众所周知,for循环是编程中必不可少的知识点:那么如何高效的写出循环呢? 我们要先知道for循环的基础样式是由自有变量自增自减和if判组成的: 1 for(条件){ 2 执行语句 3 } 而for循环 ...
- Xtrabackup 物理备份
目录 Xtrabackup 安装 Xtrabackup 备份介绍 Xtrabackup全量备份 准备备份目录 全量备份 查看全量备份内容 Xtrabackup 全量备份恢复数据 删除所有数据库 停止数 ...
- 鸟哥的linux私房菜——第九章学习(vim编辑器)
第九章vim编辑器 1.0).vi与vim Linux下文本界面的文书编辑器通常会有常常听到的就有: emacs, pico, nano, joe, 与 vim 等等. vi的优势: 所有的 Unix ...
- ASP.NET Core 中间件(Middleware)(一)
本文主要目标:记录Middleware的运行原理流程,并绘制流程图. 目录结构: 1.运行环境 2.Demo实践 3.源码追踪 4.AspnetCore内置middleware 一.运行环境 Visu ...
- Java 对象的哈希值是每次 hashCode() 方法调用重计算么?
对于没有覆盖hashCode()方法的对象 如果没有覆盖 hashCode() 方法,那么哈希值为底层 JDK C++ 源码实现,实例每次调用hashcode()方法,只有第一次计算哈希值,之后哈希值 ...