首页 > 其他分享 >实现starter组件自动装配以及可配置

实现starter组件自动装配以及可配置

时间:2023-10-09 10:35:34浏览次数:41  
标签:装配 Spring Boot 自动 组件 configurations starter 加载

实现starter组件自动装配以及可配置

自动装配的包,导入就可以进行自动装配了

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
    <version>2.1.4.RELEASE</version>
</dependency>

配置文件代码提示

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

实现starter组件自动装配以及可配置

Spring Boot自动装配原理

前面说过Spring Boot的特点就是自动装配,相信使用过Spring的读者们都体会过XML配置的复杂,而使用Spring Boot会发现除了导入依赖之外,无需过多的配置即可使用,就算需要配置时也只需要通过配置类或配置文件进行简单配置即可,这样的便利归功于Spring Boot的自动装配。接下来就了解一下Spring Boot究竟如何实现了自动装配。

学过Java的应该都听过SPI机制(JDK内置的一种服务发现机制),而Spring boot正是基于SPI机制的方式对外提供了一套接口规范(当Spring Boot项目启动时,会扫描外部引入的Jar中的META-INF/spring.factories文件,将文件中配置的类信息装配到Spring容器中),让引入的Jar实现这套规范即可自动装配进Spring Boot中。

所以想要自定义的starter组件实现自动装配,只需要在项目的 resources 中创建 META-INF 目录,并在此目录下创建一个 spring.factories 文件,将starter组件的自动配置类的类路径写在文件上即可。

项目代码-META-INF/spring.factories

// 添加项目的自动配置类的类路径
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.lucas.check.config.CheckAutoConfigure

虽然已经解决了自定义starter实现自动装配,但是有兴趣的还是接着了解一下底层自动装配的过程。那么Spring Boot是如何找到 META-INF/spring.factories 的文件并进行自动配置的呢?

深入源码解析自动装配过程

  1. Spring Boot项目在启动类上都会有一个 @SpringBootApplication 注解,这个注解可以看作是@Configuration@EnableAutoConfiguration@ComponentScan的集合,而自动装配原理就在其中的 @EnableAutoConfiguration 中,这个注解作用是开启自动配置机制。

  2. @EnableAutoConfiguration 中实现自动装配核心功能的是@Import,通过加载自动装配类AutoConfigurationImportSelector实现自动装配功能。

  3. 深入 AutoConfigurationImportSelector 代码发现该类实现了ImportSelector接口同时实现了该接口的selectImports方法,这个方法用来获取所有符合条件的类的全限定名(为什么是符合条件,只在后续按需装配中说明),并且将这些类加载进Spring容器中。

  4. 再深入

    selectImports
    

    方法中会发现这个

    getAutoConfigurationEntry()
    

    方法才是最终获取到

    META-INF/spring.factories

    文件的方法。

    protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        // 第一步:先判断是否开启了自动装配机制
        if (!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
            // 第二步:获取@SpringBootApplication中需要排除的类(exclude和excludeName属性),通过这两个属性排除指定的不需要自动装配的类
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            // 第三步:获取需要自动装配的所有配置类
            configurations = this.removeDuplicates(configurations);
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.getConfigurationClassFilter().filter(configurations);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
        }
    }
    

到这里便是SpringBoot的自动装配原理整个过程(可能描述的不完整,有兴趣的可以去找找资料看看)。

抛出问题:刚刚提到的Spring Boot只会加载符合条件的类是怎么回事?

Spring Boot其实并不会加载 META-INF/spring.factories 文件下的所有类,而是按需加载,怎么个按需加载呢?

Spring Boot可以通过@ConditionalOnXXX满足条件时加载(即按需加载),下面列举一些常用的注解:

  • @ConditionalOnBean:当容器里存在指定Bean时,实例化(加载)当前Bean。
  • @ConditionalOnMissingBean:当容器里不存在指定Bean时,实例化(加载)当前Bean。
  • @ConditionalOnClass:当类路径下存在指定类时,实例化(加载)当前Bean。
  • @ConditionalOnMissingClass:当类路径下不存在指定类时,实例化(加载)当前Bean。
  • @ConditionalOnProperty:配置文件中指定的value属性是指定的havingValue属性值时,实例化(加载)当前Bean。

标签:装配,Spring,Boot,自动,组件,configurations,starter,加载
From: https://www.cnblogs.com/firsthelloworld/p/17750874.html

相关文章

  • 界面控件DevExpress WPF地图组件,助力轻松搭建自己的地图数据服务器!
    DevExpressWPF Map控件允许用户在WPF应用程序中合并所有流行的地图服务,如Bing或OpenStreetMap。您还可以在公司网络中创建自己的地图数据服务器,Map组件完全支持矢量和笛卡尔坐标地图,以及Bing地理代码、搜索、路线和海拔服务。P.S:DevExpressWPF拥有120+个控件和库,将帮助您交付......
  • 【Azure Logic App】在Logic App中使用 Transfer XML组件遇见错误 undefined
    问题描述在AzureLogicApp中,使用TransformXML组件进行XML内容的转换,但是最近这个组件运行始终失败。 问题解答点击TransformXML组件上的错误案例,并不能查看到详细的错误消息。最后在AzureLogicApp的产品团队确认下,发现这是LogicApp自身升级后,当前LogicApp 依旧是旧版所引......
  • 【Azure Logic App】在Logic App中使用 Transfer XML组件遇见错误 undefined
    问题描述在AzureLogicApp中,使用TransformXML组件进行XML内容的转换,但是最近这个组件运行始终失败。 问题解答点击TransformXML组件上的错误案例,并不能查看到详细的错误消息。最后在AzureLogicApp的产品团队确认下,发现这是LogicApp自身升级后,当前LogicApp 依旧是......
  • vue封装搜索组件,自定义elment搜索组件
    组件案例<template><divclass="dialog-search"><el-form:inline="true"ref="ruleForm":model="formInline"class="demo-form-inlinetop-screen"><divclass="to......
  • vue3子组件页面不更新
    写在前面这是一次滑铁卢,整整找了半天时间...项目结构我有一个组件A,A中定义了一个属性data:Object,A中将data赋值给了一个reactive类型的对象R。页面中均使用R。现象描述当调用A的父组件P更新了A的data后,A的页面不更新问题分析P更新A后,A是一个新的对象,但R仍然引用旧对象,导致产......
  • 文字组件里的表格为什么分到两页
    问题:完全可以显示在一页上的表格为什么会分成两页解决方法:选取整个表格》开始》段落》换行和分页》分页组中除孤行控制以外全部取消》确定......
  • OPPO主题组件开发 - 组件内容自适应
    OPPO桌面有3*5、3*6、4*5、4*6、5*5、5*6等布局,随着布局不同,组件大小也会发生改变;不同型号手机分辨率不同,组件大小也不一致。这就要求组件内容做到自适应。说明OPPO主题组件自适应有两种表现方式,如下图所示。可以很明显的看到,第一种是根据宽高等比例缩放内容,第二种是固定内......
  • [转]oracle listener.ora中PLSExtPro 和ExtProc的作用(过时组件,官方建议删除以避免漏
    默认安装时,会安装一个PL/SQL外部程序(ExtProc)条目在listener.ora中,是oracle为调用外部程序默认配置的监听,它的名字通常是ExtProc或PLSExtProc,但一般不会使用它,可以直接从listener.ora中将这项移除,因为对ExtProc已经有多种攻击手段了,在不使用外部程序时,oracle也是建议删除的。PLSEx......
  • 安装配置kvm虚拟机,并创建虚拟机
    1、开启宿主机的CPU虚拟化功能编辑虚拟机设置--处理器--勾选虚拟化IntelVT-x/EPT或AMD-V/RVI(V).2、验证是否开启虚拟化支持[root@KVM~]#grep-Em1"vmx|svm"/proc/cpuinfoflags:fpuvmedepsetscmsrpaemcecx8apicsepmtrrpgemcacmovpatpse3......
  • 【Vue】自己编写排名组件
    一、需求分析这里我是用Echarts的柱状图,倒置下y轴x轴就实现了,然后产品说跟UI不一致我一看UI这种又给我整不会了,然后想拿Echarts改改参数搞定,同事和群友都是说自己做,不要用Echarts改 二、实现思路同事劝我用ElementUI的进度条组件来实现,进度条见:https://element.eleme.io/......