springboot的自动装配原理浅析

@SpringBootApplication

作用:标注在某个类上说明这个类是SpringBoot的主配置类 , SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;

这是一个组合注解,包含有以下几个注解:

在这里插入图片描述
@Target用来定义你的注解将应用于什么地方(例如是一个方法或者一个域)。

@ Retention用来定义该注解在哪一个级别可用,在源代码中(SOURCE)、类文件中(CLASS)或者运行时(RUNTIME)。

@Target:定义注解的作用目标(作用域)

@Target(ElementType.TYPE)
TYPE:接口、类、枚举、注解
FIELD:字段枚举的常量
METHOD:方法
PARAMETER:方法参数
CONSTRUCTOR:构造函数
LOCAL_VARIABLE:局部变量
ANNOTATION_TYPE:注解
PACKAGE:包
TYPE_PARAMETER:参数类型声明
TYPE_USE:使用的类型

@Retention 注解有一个属性 value,是 RetentionPolicy 类型的,Enum RetentionPolicy 是一个枚举类型
这个枚举决定了 Retention 注解应该如何去保留,也可理解为 @Retention 搭配枚举类型 RetentionPolicy 使用。

1RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成 .class 文件的时候,被其标注的注解被遗弃;

2RetentionPolicy.CLASS:注解被保留到class文件中,但jvm加载 .class 文件时候,被其标注的注解会被遗弃,这是默认的生命周期;

3RetentionPolicy.RUNTIME:注解不仅被保留到 .class 文件中,jvm 加载 .class 文件之后,被其标注的注解仍然存在,
所以这个时候才可能通过反射机制读取注解的信息,而前两个生命周期中,通过反射机制读取不到注解信息的;

生命周期长度 RUNTIME > CLASS > SOURCE,所以后者能作用到的地方前者一定也能作用到,但是反过来,前者能作用到的地方后者就作用不到。

1、一般如果需要在运行时去动态获取注解信息,那只能用生命周期最长的 RUNTIME 标注了,比如 @Deprecated 就是使用 RetentionPolicy.RUNTIME 来标注的;

2、如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS注解;

这个在源码中没有找到,但是参考其他博客写的 ButterKnife 就是被 RetentionPolicy.CLASS 标注的。

3、如果只是做一些检查性的操作,比如源码中的 @Override@SuppressWarnings@Native@Generated 等就是被 RetentionPolicy.SOURCE 标注的。

@Documented
作用:生成文档信息的时候保留注解,对类作辅助说明

@Inherited
简单理解就是:如果使用了这个注解,那么该类的子类就不需要再写这个注解了,该类的子类会自动的继承这个注解
最常见的例子就是写单元测试时:我们有个@SpringBootTest的主单元测试类
一般我们新写一个单元测试时不需要再写注解,而是直接继承这个主单元测试类即可。

@Inherited是一个标识,用来修饰注解
作用:如果一个类用上了@Inherited修饰的注解,那么其子类也会继承这个注解

注意:

接口用上个@Inherited修饰的注解,其实现类不会继承这个注解
父类的方法用了@Inherited修饰的注解,子类也不会继承这个注解
当用了@Inherited修饰的注解的@Retention是RetentionPolicy.RUNTIME,则增强了继承性,在反射中可以获取得到

@ComponentScan
作用:自动扫描并加载符合条件的组件或者bean,并将这个bean定义加载到IOC容器中。

@SpringBootConfiguration
springboot的配置类,标注在某个类上,表示这是一个springboot的配置类

一直查看可知:

@Configuration
public @interface SpringBootConfiguration {}

@Component
public @interface Configuration {}


@Configuration:说明是一个配置类,配置类就是对应spring的xml的配置文件。
@Component :说明启动类就是一个spring的组件,负责启动应用

@EnableAutoConfiguration

开启自动装配功能,@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;
第一次点进去:

@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})

@AutoConfigurationPackage :自动配置包
@AutoConfigurationPackage继续点进去:

@Import({Registrar.class})
public @interface AutoConfigurationPackage {}

@Import({Registrar.class})

@import :Spring底层注解@import , 给容器中导入一个组件

Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器 ;

@Import({AutoConfigurationImportSelector.class})
给容器导入组件
AutoConfigurationImportSelector :自动配置导入选择器,那么它会导入哪些组件的选择器呢?我们点击去这个类看源码:
其中的关键就是spring.factories

打开spring.factories我们可以看到自动配置的文件了。
在这里插入图片描述

所以,自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件 ,并将其中对应的 org.springframework.boot.autoconfigure. 包下的配置项,通过反射实例化为对应标注了 @Configuration的JavaConfig形式的IOC容器配置类 , 然后将这些都汇总成为一个实例并加载到IOC容器中。

总结:

  1. SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值

  2. 将这些值作为自动配置类导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作;

  3. 整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;

  4. 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件,并配置好这些组件 ;

  5. 有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作;

SpringApplication.run分析

分析该方法主要分两部分,一部分是SpringApplication的实例化,二是run方法的执行;

SpringApplication

这个类主要做了以下四件事情:

1、推断应用的类型是普通的项目还是Web项目

2、查找并加载所有可用初始化器 , 设置到initializers属性中

3、找出所有的应用程序监听器,设置到listeners属性中

4、推断并设置main方法的定义类,找到运行的主类

run方法流程分析:

在这里插入图片描述

参考:https://mp.weixin.qq.com/s/hzRwZvjYSX-dy-9Drz94aQ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值