如何通过一张图搞懂springBoot自动注入原理

目录
  • @SpringBootApplication注解解读
  • 1.@SpringBootConfiguration
  • 2.@EnableAutoConfiguration
    • @Inherited
    • @AutoConfigurationPackage
    • AutoConfigurationImportSelector.class
  • 3.@ComponentScan
  • 总结

@SpringBootApplication注解解读

为什么我们的启动类上标注一个@SpringBootApplication注解,再加一个run()方法就可运行起来,可以看出我们的@SpringBootApplication注解是多么的强大。

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

@SpringBootApplication其实是由三个字注解来合成的。我们可以完全用这个三个注解来替换掉@SpringBootApplication。

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @ComponentScan.Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @ComponentScan.Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

我们来说下这三个注解的一个作用,分别做了什么事情,为什么区区几个注解就可以让我们的程序跑起来。

1.@SpringBootConfiguration

其实点击进去就是一个 @Configuration,没什么特别的,学习过spring的朋友都知道,这是用于标注一个配置类的。

2.@EnableAutoConfiguration

重点就是在于@EnableAutoConfiguration 这个注解,我们先看下他的一个构成。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

@Inherited

@Inherited : 如果标注此注解标识子类也可以进行继承,这个不太重要

我们先来看.@EnableAutoConfiguration 注解中的@AutoConfigurationPackage注解里面的内容有什么 ? 可以看到导入了一个AutoConfigurationPackages.Registrar类型的组件

@AutoConfigurationPackage

@AutoConfigurationPackage:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {

我们来看下导入的这个AutoConfigurationPackages.Registrar组件做了什么事情?

registerBeanDefinitions? registerBeanDefinitions是不是就是往我们的容器中添加组件啊?那我们来看看他具体导入了那些组件。你可以将断点打在这两个方法上

	static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

		@Override
		public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
			register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
		}

		@Override
		public Set<Object> determineImports(AnnotationMetadata metadata) {
			return Collections.singleton(new PackageImports(metadata));
		}

	}

只要把BeanDefinition注册进去,往后我们只要调用getBean()就会得到该对象,当然不一定得我们自己调用,spring在底层最后刷新容器的时候,就会初始化所有的单实例bean,这也就是为什么我们直接使用相关注解就可以获取到该对象的原有。

getBean()有两层意思:

1.容器中有直接从缓存中获取

2.容器中没有直接创建一个,也就是走bean的生命周期创建

AutoConfigurationImportSelector.class

@Import(AutoConfigurationImportSelector.class) 核心组件,我们来看看他做了什么事情。

AutoConfigurationImportSelector他呢继承了DeferredImportSelector,DeferredImportSelector他呢有个内部接口Group,而Group中又有个方法process()
所以我们来到AutoConfigurationImportSelector中的process()方法打上断点进行观察

	@Override
		public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
			Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,
					() -> String.format("Only %s implementations are supported, got %s",
							AutoConfigurationImportSelector.class.getSimpleName(),
							deferredImportSelector.getClass().getName()));
			AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
					.getAutoConfigurationEntry(annotationMetadata);
			this.autoConfigurationEntries.add(autoConfigurationEntry);
			for (String importClassName : autoConfigurationEntry.getConfigurations()) {
				this.entries.putIfAbsent(importClassName, annotationMetadata);
			}
		}

这个方法一上来就要获取一些自动注入的条目autoConfigurationEntry,那我们看下他是怎么获取的,获取的究竟是什么东西?
通过堆栈信息我们可以看到是通过invokeBeanDefinitionRegistryPostProcessors()这个方法调用过来的,说明在工厂初始化完毕,你可以往里面仍一些bean的定义信息了。

进去就是这个方法

	protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
		configurations = removeDuplicates(configurations);
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);
		configurations = getConfigurationClassFilter().filter(configurations);
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}

我们再进入这个方法

在进入loadFactoryNames()方法中

那我们去看看这个文件里面有什么

结合上面的代码他是不是要加载org.springframework.boot.autoconfigure.EnableAutoConfiguration里面的内容,这些就是一些配置类的信息

其实这个文件 spring.factories 里面的每一个类的权限的名称就是一个配置类,只不过springBoot把这些配置类都写好了,在我们某些场景需要的时候直接给你注入就行,这就说明了我们不用写那么多配置文件的原因。

我随便点击一个类进去看看

加载完成后: 怎么多?是不是全部第用得上啊?

你看下面的代码,是不是要排除,移除掉,过滤掉一些啊,排除就是我们自己在注解中写的排除属性进行排除,让后就是经过一系列的筛选过滤。

最后将这些信息put到entries中

3.@ComponentScan

@ComponentScan这个注解的功能就是扫描当前类上标注此注解所在包路径的所有类,这也就是为什么我们需要把主启动类放在最外面的原有,如果你想把配置类放在别的地方,那你就得自己手动指定包扫描路径.

最后奉上超清晰的图

总结

到此这篇关于如何通过一张图搞懂springBoot自动注入原理的文章就介绍到这了,更多相关springBoot自动注入原理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Spring Boot自动注入的原理分析

    前言 我们经常会被问到这么一个问题:SpringBoot相对于spring有哪些优势呢?其中有一条答案就是SpringBoot自动注入.那么自动注入的原理是什么呢? 我们进行如下分析. 1:首先我们分析项目的启动类时,发现都会加上@SpringBootApplication这个注解,我们分析这个继续进入这个注解会发现,它是由多个注解组成的,如下 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @I

  • 如何通过一张图搞懂springBoot自动注入原理

    目录 @SpringBootApplication注解解读 1.@SpringBootConfiguration 2.@EnableAutoConfiguration @Inherited @AutoConfigurationPackage AutoConfigurationImportSelector.class 3.@ComponentScan 总结 @SpringBootApplication注解解读 为什么我们的启动类上标注一个@SpringBootApplication注解,再加一个r

  • JavaScript两张图搞懂原型链

    目录 1.原型的关系 2.原型链 3.结语 前言: 我们上一篇文章介绍了JavaScript原型,为什么不将原型链一起介绍了呢?因为JavaScript中的原型链是一个难点,也是一个面试必问的考点,现在就来学习一下. 1.原型的关系 在JavaScript中的每个函数都会有一个prototype属性,这个属性又会返回一个原型,原型又有一个constructor属性,这个属性指向与之关联的构造函数.通过构造函数实例化的对象会有一个__proto__属性,这个__proto__属性指向与构造函数的p

  • 一篇文章带你彻底搞懂VUE响应式原理

    目录 响应式原理图 编译 创建compile类 操作fragment 获取元素节点上的信息 获取文本节点信息 操作fragment 响应式 数据劫持 收集依赖 响应式代码完善 Dep类 全局watcher用完清空 依赖的update方法 需要注意的一个地方 双剑合璧 总结 首先上图,下面这张图,即为MVVM响应式原理的整个过程图,我们本篇都是围绕着这张图进行分析,所以这张图是重中之重. 响应式原理图 一脸懵逼?没关系,接下来我们将通过创建一个简单的MVVM响应系统来一步步了解这个上图中的全过程.

  • 一文带你搞懂PHP对象注入

    目录 背景 漏洞案例 PHP类和对象 php magic方法 php对象序列化 序列化magic函数 php对象注入 常见的注入点 其他的利用方法 如何利用或者避免这个漏洞 结论 背景 php对象注入是一个非常常见的漏洞,这个类型的漏洞虽然有些难以利用,但仍旧非常危险,为了理解这个漏洞,请读者具备基础的php知识. 漏洞案例 如果你觉得这是个渣渣洞,那么请看一眼这个列表,一些被审计狗挖到过该漏洞的系统,你可以发现都是一些耳熟能详的玩意(就国外来说) WordPress 3.6.1 Magento

  • SpringBoot自动配置原理,你真的懂吗?(简单易懂)

    概述 上面博文(SpringBoot简介与快速搭建)我们简单的介绍了什么是SpringBoot,以及如何使用SpringBoot,但是我们对于SpringBoot的基本原理并没有介绍,这篇博文我们重点介绍SpringBoot是如何实现的自动配置. 依赖管理 在我们的pom文件中最核心的依赖就一个: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-star

  • 一文搞懂MySQL运行机制原理

    目录 前言 MySQL服务器体系架构 网络连接层 服务层 存储引擎层 系统文件层 服务器处理客户端请求 连接管理 解析与优化 查询缓存 语法解析 查询优化 存储引擎 小结 前言 前文我们了解了MySQL采用客户端/服务器架构,用户通过客户端程序发送增删改查需求,服务器程序收到请求后处理,并且把处理结果返回给客户端.这篇文章主要看下MySQL服务端是如何处理客户端的请求,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助. MySQL服务器体系架构 MySQL Server架构自顶向下大致可以分网

  • springboot自动配置原理解析

    前言 小伙伴们都知道,现在市面上最流行的web开发框架就是springboot了,在springboot开始流行之前,我们都用的是strust2或者是springmvc框架来开发web应用,但是这两个框架都有一个特点就是配置非常的繁琐,要写一大堆的配置文件,spring在支持了注解开发之后稍微有些改观但有的时候还是会觉得比较麻烦,这个时候springboot就体现出了它的优势,springboot只需要一个properties或者yml文件就可以简化springmvc中在xml中需要配置的一大堆

  • springboot自动配置原理以及spring.factories文件的作用详解

    目录 一.springboot 自动配置原理 二.spring.factories文件的作用 spring.factories 的妙用 什么是 SPI 机制? Spring Boot 中的 SPI 机制 Spring Factories 实现原理是什么? Spring Factories 在 Spring Boot 中的应用 一.springboot 自动配置原理 先说说我们自己的应用程序中Bean加入容器的办法: package com.ynunicom.dc.dingdingcontract

  • SpringBoot自动配置原理详解

    目录 阅读收获 一.SpringBoot是什么 二.SpringBoot的特点 三.启动类 3.1 @SpringBootApplication 四.@EnableAutoConfiguration 4.1 @AutoConfigurationPackage 4.2  @Import({AutoConfigurationImportSelector.class}) 五.流程总结图 六.常用的Conditional注解 七.@Import支持导入的三种方式 阅读收获 理解SpringBoot自动配

  • SpringBoot自动配置原理分析

    目录 前言 一.启动类 1.1.@SpringBootConfiguration 1.2.@EnableAutoConfiguration 1.3.@ComponentScan 1.4.探究方向 二.@SpringBootConfiguration 三.@EnableAutoConfiguration 3.1.@AutoConfigurationPackage 3.2.@Import(AutoConfigurationImportSelector.class) 3.2.1.getCandidat

随机推荐