当前位置: 首页 > web >正文

SpringBoot自动配置原理(二)

1.通过SpringFactoriesLoader.loadFactoryName加载  EnableAutoConfiguration.class,读取SpringBoot自动配置类。

@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>");for(String name : SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,null)){System.out.println(name);}System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>");//返回配置类的类名List<String> names = SpringFactoriesLoader.loadFactoryNames(MyImportSelector.class,null);return names.toArray(new String[0]);}

读取到的是spring.factories文件下配置的类

2.遇到的问题

 同名的第三方bean导入失败, 以bean1为例测试。

package com.example.springdemo.demos.a04;/*** @author zhou* @version 1.0* @description TODO* @date 2025/8/15 21:32*/
public class Bean1 {private String name;public Bean1(String name){this.name = name;}@Overridepublic String toString() {return "bean1的name:" + name;}}
package com.example.springdemo.demos.a04;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.*;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.core.type.AnnotationMetadata;import java.util.List;/*** @author zhou* @version 1.0* @description TODO* @date 2025/8/15 21:30*/
public class TestAutoConfiguration {public static void main(String[] args) {GenericApplicationContext context = new GenericApplicationContext();//springBoot默认设置为false,同名的bean不允许第三方覆盖context.getDefaultListableBeanFactory().setAllowBeanDefinitionOverriding(false);context.registerBean("config",Config.class);//添加bean工厂后处理器context.registerBean(ConfigurationClassPostProcessor.class);context.refresh();for (String name:context.getBeanDefinitionNames()) {System.out.println(name);}System.out.println(">>>>>>>>>>>>>>>>>>>");System.out.println(context.getBean(Bean1.class));}@Configuration //本项目配置类@Import({MyImportSelector.class})static class Config{@Beanpublic Bean1 bean1(){return new Bean1("本项目");}}static class MyImportSelector implements ImportSelector{@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {/*System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>");for(String name : SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,null)){System.out.println(name);}System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>");*///返回配置类的类名List<String> names = SpringFactoriesLoader.loadFactoryNames(MyImportSelector.class,null);return names.toArray(new String[0]);}}@Configurationstatic class AutoConfiguration1{@Beanpublic Bean1 bean1(){return new Bean1("第三方");}}@Configurationstatic class AutoConfiguration2{@Beanpublic Bean2 bean2(){return new Bean2();}}
}

如果本类的bean和自动配置类的bean是同名的话,SpringBoot会做以下设置,不允许第三方覆盖

context.getDefaultListableBeanFactory().setAllowBeanDefinitionOverriding(false);

      它先是使用了自动配置类里面的bean1,后面报错不能注册本地配置的bean1。如何解决这个问题?(配置类的bean1先使用,再是找本地类,这样是否合理)

3.解决办法

       导入类变为延迟加载的类 DeferredImportSelector(调整顺序,先找本地配置的bean,后找自动配置的bean,这样比较合理),延迟加载第三方配置,先让本类生效。

在第三方的bean上加上@ConditionalOnMissingBean注解
@Configurationstatic class AutoConfiguration1{@ConditionalOnMissingBean@Beanpublic Bean1 bean1(){return new Bean1("第三方");}}

结果如下:

本项目有的bean优选使用本项目配置的,如果缺失了再使用第三方的bean。

http://www.xdnf.cn/news/18089.html

相关文章:

  • [Linux] RAID存储技术
  • TDengine 3.3.7.0 版新功能(BLOB 数据类型)
  • LangGraph实战指南:如何构建一个深度研究Agent
  • 测试工程师的AI转型指南:从工具使用到测试策略重构
  • MySQL 配置性能优化赛技术指南
  • H20芯片与中国的科技自立:一场隐形的博弈
  • K8S HPA 弹性水平扩缩容 Pod 详解
  • 力扣 hot100 Day75
  • C#WPF实战出真汁08--【消费开单】--餐桌面板展示
  • implement copy file content to clipboard on Windows
  • 某智慧教育平台登录流程分析
  • php版的FormCreate使用注意事项
  • 树、哈夫曼树以及二叉树的各种操作
  • 如何使用嵌入模型创建本地知识库Demo
  • Rocky Linux 9.2:从 /home 分区释放 10G 空间扩容到 / 根分区
  • 二进制为什么使用记事本读取会出乱码
  • eChart饼环pie中间显示总数_2个以上0值不挤掉
  • 0815 UDP通信协议TCP并发服务器
  • Mac (三)如何设置环境变量
  • 深入理解 Python 元类中的 __prepare__ 方法:掌控类属性定义顺序的艺术
  • docker镜像解决的一些问题
  • 双重调度(Double Dispatch):《More Effective C++》条款31
  • [Linux] Linux网络管理
  • 16-集合的Stream编程
  • 宋红康 JVM 笔记 Day03|内存结构概述、类加载器与类的加载过程、类加载器分类
  • 深入解析 @nestjs/typeorm的 forRoot 与 forFeature
  • C++面试题及详细答案100道( 31-40 )
  • 算法题Day2
  • Python 类元编程(元类的特殊方法 __prepare__)
  • MixOne:Electron Remote模块的现代化继任者