✔自从Spring Boot
的出现,让Java
的基本系统搭建过程变得更简单,不需要关心很多的配置文件,也不需要去关心市面上各版本的包存在版本冲突等等的问题,Spring Boot遵守约定大于配置的开发原则
,大大就是减少了人为的配置,简化了项目开发过程。
SpringBoot如何实现的自动装配?
、SpringBoot中starter的原理?
、Spring Boot核心注解有哪些?
等等都是值得我们深入了解,也是检测你是否真正的使用过Spring Boot
,或者是否对Spring Boot
项目具有一定的基础。
🌈今天我们就是来说一下Spring Boot
中的自动装配原理,自动装配是Spring Boot
中的一个非常重要的,也是非常具有特色的功能,下面就来看一下吧。
自动装配的整个过程分析
从启动类开始看
说起Spring Boot
中的自动装配,首先要从Spring Boot
的启动类开始看。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
这是一个基本的Spring Boot
启动类,我们主要看SpringBootApplication
这个注解,点进去源码,看一下具体的实现。
如上图所示,SpringBootAplication是一个复合注解。,关键看@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan
这三个注解:
@SpringBootConfiguration
它实际上就是一个 @Configuration
注解,这个注解大家应该很熟悉了,加上这个注解就是为了让当前类作为一个配置类交由 Spring
的 IOC
容器进行管理,因为前面我们说了,Spring Boot
本质上还是Spring
,所以原属于Spring
的注解@Configuration
在SpringBoot
中也可以直接应用。
@ComponentScan
@Configuration
注解的话,我们应该不会陌生,用于定义 Spring
的扫描路径,等价于在 xml
文件中配置 <context:component-scan>
,假如不配置扫描路径,那么 Spring
就会默认扫描当前类所在的包及其子包中的所有标注了 @Component
,@Service
,@Controller
等注解的类。
@EnableAutoConfiguration
@EnableAutoConfiguration
才是实现自动装配的核心,翻译为:自动配置的意思,也可以说自动装配,既然是要聊自动装配原理,它是由@AutoConfigurationPackage
和@Import
注解组成的复合注解。
@EnableAutoConfiguration开启自动装配注解
简单说下在此之上的注解,如果你在项目自定义过注解的话,就能很好的分辨这几种的概念了,比如自定义日志注解。
@Target
@Target
注解就是表明该注解类能够作用的范围,也就是注解在哪,比如:类、方法、接口、参数等,下面是它的一些参数:
参数 | 说明 |
---|---|
@Target(ElementType.TYPE) | 接口、类、枚举、注解 |
@Target(ElementType.FIELD) | 字段 |
@Target(ElementType.METHOD) | 方法 |
@Target(ElementType.PARAMETER) | 方法参数 |
@Target(ElementType.CONSTRUCTOR) | 构造函数 |
@Target(ElementType.LOCAL_VARIABLE) | 局部变量 |
@Target(ElementType.ANNOTATION_TYPE) | 解 |
@Target(ElementType.PACKAGE) | 包 |
里面的参数是可以多选的,使用方法比如:@Target({ElementType.METHOD,ElementType.TYPE})。
@Retention
@Retention
注解是保留说明,也就是表明这个注解的类在哪里保留,它有三个属性:
1️⃣ RetentionPolicy.SOURCE - 这种类型的Annotations
只在源代码级别保留,编译时就会被忽略
2️⃣ RetentionPolicy.CLASS - 这种类型的Annotations
编译时被保留,在class
文件中存在,但JVM
将会忽略
3️⃣ RetentionPolicy.RUNTIME - 这种类型的Annotations
将被JVM
保留,所以他们能在运行时被JVM
或其他使用反射机制的代码所读取和使用。
@Documented
@Documented
注解表明这个注解应该被javadoc
工具记录,默认情况下,javadoc
是不包括该注解的,但是如果声明注解时指定了@Documented
,那么它就会被javadoc之类的工具处理,该注解类型信息也会被包括在生成的文档中。
@Order
@Order
标记定义了组件的加载顺序,这个标记包含一个value
属性。属性接受整形值。如:1/2 等等。值越小拥有越高的优先级。Ordered.HIGHEST_PRECEDENCE
这个属性值是最高优先级的属性,它的值是-2147483648,对应的最低属性值是Ordered.LOWEST_PRECEDENCE
,它的值是2147483647。
@Inherited
用于加强继承效果。
@Import
事实上,@Import注解才是自动装配的核心,Import
注解导入了AutoConfigurationImportSelector
类,使用Import
导入的类都会加载到Spring ioc
容器中。
AutoConfigurationImportSelector
AutoConfigurationImportSelector
类实现了诸多接口,有:DeferredImportSelector
, BeanClassLoaderAware
, ResourceLoaderAware
,
BeanFactoryAware
, EnvironmentAware
, Ordered
,自动装配的实现逻辑其实就是在selectImports()
方法中,如图所示:
继续分析源码,有一个getCandidateConfigurations
方法,进入看一下代码情况,上图看到一个getAutoConfigurationEntry()
获取自动配置入口的方法,点击进入方法:
找到getCandidateConfigurations
方法:
这里存在一个断言,意思是当无法正确的找到spring.factories
文件时,会报: No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.
这个方法其实就是加载spring.factories
文件,我们可以看看这个文件都有哪些具体内容,通过IDEA的当前类定位进行寻找,如图所示:
我们可以看看spring.factories
文件的内容:
可以看出,通过selectImports
方法,取到该文件下的一系列类名,随后将这些类自动加载至IOC
容器中,实际上这些类都属于内部存在自动配置的类,同样可以发现这些类名都是以AutoConfiguration
结尾的。
总结
Spring Boot
自动装配原理实际上就是通过@EnableAutoConfiguration
注解,加载AutoConfigurationImportSelector
类中的selectImports
方法,进而扫描MATE-INF
下的spring.factories
文件下的自动配置类,并将其装配至Spring IOC容器
的过程。