看看SpringBoot的自动装配原理

2024-09-02 03:28

本文主要是介绍看看SpringBoot的自动装配原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SpringBoot的自动装配原理

明天面试浅浅复习一下八股文

面试官:说一下springboot的自动装配

像以前开发的时候,配置文件需要用xml和java配置类进行显式配置,一整就整一大堆的配置文件

then 什么是自动装配?

Spring boot 定义了一套自己的规范,在Spring Boot启动的时候会扫描有什么外部的jar包的META-INF/spring.factories,然后加载里面的配置文件到Spring里面,像那些自己写的starter就只需要按照Spring boot定的规则定义文件就行了。

简单理解就是自动装配就是通过一些注解和一些简单的配置就可以在Spring boot中使用第三方的某些功能。

如何实现自动装配?

自动装配的核心就是@SpringBootApplication

打开这个类look look,这个版本是3.x的SpringBoot

更新太快了,刚刚才开始摸两下java11,3.x的spirng就需要java17只吃了,卷烂了卷烂了

SpringBootApplication.java

@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) }) // 这个玩意就是扫包的,扫描那些有标注@Component的包,通过定义不扫什么包,比如这个excludeFilters玩意就是用来定义不扫什么包的
public @interface SpringBootApplication

@SpringBootConfiguration

Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration // 注明这个也是个配置类
@Indexed // 作为元注解声明注解,可以减少应用启动的速度,下面稍微展开一下
public @interface SpringBootConfiguration {@AliasFor(annotation = Configuration.class)boolean proxyBeanMethods() default true;
}

@Indexed:当Spring Boot需要扫描的类太多的时候,@ComponentScan就是这个类需要扫描的类太多的时候,应用启动的时间就会变长。这个注解的用处就是用来解决这个问题的,再项目进行编译打包的时候,会自动生成被@Indexed注释的类的解析结果的文件META-INF/spring.components,当Spring开始进行上下文扫描的的时候,会直接读取被@Indexed处理的文件而不需要进行扫描,这样就可以减少应用的启动时间。

@EnableAutoConfiguration:实现自动装配的核心注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage // 将main包下面的包注册到容器中
@Import(AutoConfigurationImportSelector.class) // 加载需要自动装配的类
public @interface EnableAutoConfiguration {/*** Environment property that can be used to override when auto-configuration is* enabled.*/String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";/*** Exclude specific auto-configuration classes such that they will never be applied.* @return the classes to exclude*/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*/String[] excludeName() default {};}

还需要继续深入看看这个AutoConfigurationImportSelector.class

// 继承体系
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered // DeferredImportSelector 这个玩意继承了一个叫 ImportSelector的接口
public interface DeferredImportSelector extends ImportSelector // 然后我们现在回到AutoConfigurationImportSelector这个类中,有点混乱了写的
public String[] selectImports(AnnotationMetadata annotationMetadata) {// 判断自动装配是否打开,简单的理解为上面的EnableAutoConfiguration注解if (!this.isEnabled(annotationMetadata)) {return NO_IMPORTS;} else {// 然后获取需要装配的bean,这个this.getAutoConfigurationEntry是主要负责加载自动配置类的,主要就是获取所有的自动装配的类,然后从上面也有提过的`META-INF/spring.factories`来加载配置类AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}}

这个方法主要是读取所有符合Spring Boot加载条件的的类名,然后把这些类加载到IoC容器中。

文字总结一下,这个大致的流程

  1. 先在AutoConfigurationImportSelector判断自动装配开关是否打开(spring.boot.enableautoconfiguration=true
  2. 然后去获取用于EnableAutoConfiguration注解中的 exclude 和 excludeName。这个exclude都是在AnnoctionAttribuite的两个key
  3. 然后再去加载META-INF/spring.factories,XXXAutoConfiguration的作用就是按需加载组件。(在idea的项目文件树中,有一个目录叫做External Libraries,打开里面的目录可以看到会有一个spring.factories的文件的,里面会有一些配置的信息)
  4. 在这些文件里面会有很多个配置文件,他们并不会全部一次加载,加载的时候会有一个筛选的方法,这个注解叫@ConditionalOnClass(以后再看看这个东西怎么个回事,懒惰了不看了)

以前有个面试官问过我,如何实现一个starter?顺手也总结一下

  1. 首先要创建一个工程,取个名字 test-spring-boot-starter
  2. 然后这个工程要是一个maven的工程,或者说是gradle也行,引入关于Spring Boot的相关依赖

pom文件的伪代码

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>${挑选适合你的版本}</version></dependency>
</dependencies>
  1. 然后这个时候,创建一个xxxxAutoConfiguration
  2. 紧接着需要再这个工程下面,创建一个上面提了很多次的spring.factories,需要有这个玩意才能扫到你。(哦还需要一个META-INF做目录)
  3. 然后就可以测试一下了,随便创建一个新的工程,然后在你的pom文件里加入一个引入一个starter
<dependencies><dependency><groupId>org.mtc.test</groupId><artifactId>test-spring-boot-starter</artifactId><version>${你maven创建的时候自己设置的版本}</version></dependency>
</dependencies>

这就ok了

再一个大的总结

主要的核心就是扫描配置就是基于Spring factories,这个四舍五入等于事先约定好的配置文件,也就是Spring Boot所说的约定大于配置,不需要在通过xml进行配置。

@EnableAutoConfiguration 开启自动装配

自动配置类根据@Conditional来进行筛选按需加载

然后通过引入(eg. pom)的形式来使用

done

这篇关于看看SpringBoot的自动装配原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1128862

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听