ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

springboot自动装配底层实现原理

2022-03-07 04:31:10  阅读:196  来源: 互联网

标签:装配 这个 springboot 配置文件 配置 组件 注解 class 底层


SpringBoot自动装配原理

1.@SpringBootApplication

@SpringBootApplication		//主启动类的注解
public class ShiroSpringbootApplication {

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

}

2.核心三大注解

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

点进去之后会发现,作为SpringBoot配置的三个核心注解

@SpringBootConfiguration		
@EnableAutoConfiguration
@ComponentScan

1、@SpringBootConfiguration

​ 追进去是咋们的@Configuration注解, 代表当前是一个核心配置类

2、@ComponentScan

​ 这是指定我们要扫描哪些,Spring注解

3、@EnableAutoConfiguration

​ 点进去之后会发现除了其他基本注解外,主要核心就是以下两个

@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})

(1)@AutoConfigurationPackage

​ 自动配置包,点进去之后会发现@Import这个组件

@Import({Registrar.class}) 相当于给容器中导入一个这个组件

​ 当我我追踪这个Registrar.class会发现这个类重写了两个方法

public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
    AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName());
}

public Set<Object> determineImports(AnnotationMetadata metadata) {
    return Collections.singleton(new AutoConfigurationPackages.PackageImport(metadata));
}

Registrar.class里面的registry方法:

Registrar作用:把某一个包下的组件注册进去

​ 通过registry给容器中导入一系列组件

  • AnnotationMetadata相当于我们注解的元信息,而这个注解指的是AutoConfigurationPackage,由于这个注解@EnableAutoConfiguration里的组成注解,也是@SpringBootApplication下的元注解,所以说这个注解是针对于主启动类下我们的MainApplication所以说,我们的metadata元信息标在这个类下

new AutoConfigurationPackages.PackageImport(metadata)).getPackageName(),通过通过包导入的方法,获取到元数据对应的包名,而这个包名正好对应我们项目的包名,然后讲我们包下的组件封装到我们的register里面去,通过register()这个方法批量注册进去。

换句话说就是register()这个方法把某一个包的组件注册到容器中,而这个包就是我们Main主启动类对应的包

(2)@Import({AutoConfigurationImportSelector.class})

​ 这个注解相当于给容器中导入一些组件

​ 点进去后,会发现这个方法

.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);

获取所有所有配置的集合

我们通过debug发现,候选配置有很多个

List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);

this.getCandidateConfigurations(annotationMetadata, attributes);这个方法会进入到我们

对于里面的一些配置会通过我们spring工厂的加载器,进行一个加载操作

List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());

.loadFactoryNames(),点进去会有 SpringFactoriesLoader.class.getClassLoader();

SpringFactoriesLoader这个方法里面

最终通过这个方法加载得到一个Map<String,List>这样的一个集合,即得到了我们所有的组件,

而在此之后classLoader.getResources()方法会获取我们的资源文件

有个META-INF/spring.factories路径

这个方法会默认扫描在我们当前系统所有META-INF/spring.factories位置的文件

而最核心的就是这个spring-boot-autoconfigure-2.6.3.jar这个包

我们打开当前的spring.factories,可以看到我们springboot全场景的自动配置都导进来了

可以说文件写死了spring-boot-启动就要给容器中加载所有配置;

虽然我们127个场景的所有自动配置在启动时候默认是是全部加载,但是它会通过按需开启自动导入配置项

即我们每个场景中的以后缀名为AutoConfiguration配置文件中的@Conditional(条件装配注解),以这个为参照,最终会按需装配

若我们有使用其中的个别场景

我们进入这个场景的AutoConfiguration配置文件,若想更改配置,我们可以通过在yml中,并!!根据该配置文件绑定的对应Properties文件中定义的内容来修改

而这些属性或通过

利用该注解定义的前缀进行封装,我们可以通过对应的Properties文件中对应的属性进行修改

大体流程:

xxxxxxxxAutoConfiguration---> 组件 --->xxxxProperties里面的属性 --->application.properties

springboot的一个设计模式

springboot会在底层配好所有的组件,但是如果用户自己配置了以用户的优先,从@ConditionOnMissBean这个注解可以看出

在这个方法下的内容就就是,去除一些不要的,排斥的,或者重复的配置,最后返回configurations

@EnableAutoConfiguration总结

  • SpringBoot先加载所有的自动配置类 xxxxAutoConfiguration
  • 每个自动配置类按条件生效,默认都会绑定配置文件指定的值。即xxxxProperties里面拿,xxxProperties配置文件进行了绑定。
  • 生效的配置类就会给容器中装配很多组件
  • 只要容器中有这些组件,相当于这些功能就有了
  • 定制化配置
    • 用户可以通过@Bean这样的方式替换底层的主键
    • 用户可以根据组件绑定的配置文件,通过调用改属性去进行修改

标签:装配,这个,springboot,配置文件,配置,组件,注解,class,底层
来源: https://www.cnblogs.com/striveliuxing/p/15974359.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有