Spring框架中如何自动装配Map类型的Bean并注入所有子类实例

 更新时间:2026年09月06日 11:11:56   作者:@航空母舰  
想知道Spring如何自动装配Map<String,T>类型的Bean吗?本文详细解释了为什么Spring能自动收集所有OssLogic子类到Map中,以及bean名称的命名约定和运行时如何按vendorCode分发处理,掌握这一特性,新增运营商处理逻辑只需新建类并遵循命名规范,无需修改任何注册代码

在Spring框架中,自动装配(Auto-wiring)是Spring容器自动将对象注入到其他对象中,以减少手动配置的需求。

当你使用Map<String, T>类型的依赖时,Spring提供了几种特殊的方式来自动装配这些Map类型的bean

1. 为什么能"自动收集"所有子类

  @Autowired
  private Map<String, OssLogic> ossLogicMap;

这是 Spring 的一个内置特性:

当注入目标类型为 Map<String, T> 时,Spring 会把容器中所有的 T 类型(及其子类)Bean 全部收集进这个 Map,key 是 bean 名称,value 是对应的 Bean 实例。

所以这里并不需要手动一个个注册。

只要某个类满足:

  • 是 OssLogic / BaseLogic 的子类(或本身)
  • 被 Spring 管理为 Bean(项目里用 @Configuration 标注,等价于 @Component)

例如 BjlhOssLogic extends OssLogic(@Configuration),它们都会被自动装进对应的 Map。

2. bean 名称的命名约定

bean 名称由类名首字母小写得到,例如:

BjlhOssLogic → beanName = bjlhOssLogic

init() 启动时按命名约定从 beanName 反推 vendorCode

3. 运行时如何分发

注册完成后,OssLogic自身注入了 OssVendorRegistry,通过 vendorCode 查表找到对应处理器,找不到则回退到通用逻辑:

  public String getRealCalling(String calling, String callType, String oldCalling, String vendorCode) {
    OssLogic handler = vendorRegistry.findOssLogic(vendorCode);
    if (handler != null) {
      return handler.getRealCalling(calling, callType, oldCalling);
    }
    log.debug("运营商 {} 无专门号码标准化处理逻辑,使用原始号码", vendorCode);
    return calling;

新增一个运营商的处理逻辑时,只需新建一个继承 OssLogic的类,用 @Configuration 标注,且类名遵循 {vendorCode}OssLogic 约定即可,无需修改任何注册代码,Spring 启动时会自动把它收进 Map,init() 自动完成注册。

完整代码

import lombok.extern.slf4j.Slf4j;
import net.icsoc.ark.api.common.oss.detail.OssLogic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

/**
 * OSS 运营商注册中心,利用 Spring Map 自动注入收集所有 OssLogic 子类 Bean。
 * <p>
 * 核心机制:
 * <ul>
 *   <li>通过 {@code Map<String, OssLogic>} 自动注入所有子类</li>
 *   <li>按命名约定 {@code {vendorCode}OssLogic 从 beanName 提取 vendorCode</li>
 *   <li>特殊 vendorCode(含 - 等字符)通过別名映射处理</li>
 *   <li>未找到对应的处理器时返回 null,调用方使用通用规则回退</li>
 * </ul>
 *
 * @author hudeyong
 */
@Component
@Slf4j
public class OssVendorRegistry {

  @Autowired
  private Map<String, OssLogic> ossLogicMap;

  private final Map<String, OssLogic> vendorOssLogicCache = new HashMap<>();

  @PostConstruct
  public void init() {
    // 注册 OssLogic 映射
    if (ossLogicMap != null) {
      for (Map.Entry<String, OssLogic> entry : ossLogicMap.entrySet()) {
        String beanName = entry.getKey();
        // beanName 格式如 "bjlhOssLogic",去掉 "OssLogic" 后缀得到 vendorCode
        String vendorCode = beanName.replace("OssLogic", "");
        vendorOssLogicCache.put(vendorCode, entry.getValue());
        log.info("注册 OssLogic: {} -> {}", vendorCode, entry.getValue().getClass().getSimpleName());
      }
    }
  }

  /**
   * 根据 vendorCode 查找 OssLogic
   *
   * @param vendorCode 运营商代码
   * @return 对应的 OssLogic,找不到返回 null
   */
  public OssLogic findOssLogic(String vendorCode) {
    return vendorOssLogicCache.get(vendorCode);
  }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java用itextpdf导出PDF方法(通俗易懂)

    Java用itextpdf导出PDF方法(通俗易懂)

    因为项目需要导出PDF文件,所以去找了一下能够生成PDF的java工具,这篇文章主要给大家介绍了关于Java用itextpdf导出PDF的相关资料,文中介绍的方法通俗易懂,需要的朋友可以参考下
    2023-07-07
  • Spring Mvc下实现以文件流方式下载文件的方法示例

    Spring Mvc下实现以文件流方式下载文件的方法示例

    这篇文章主要介绍了Spring Mvc下实现以文件流方式下载文件的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05
  • 浅谈Spring Batch在大型企业中的最佳实践

    浅谈Spring Batch在大型企业中的最佳实践

    本篇文章主要介绍了浅谈Spring Batch在大型企业中的最佳实践,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • Nett中的心跳机制与断线重连详解

    Nett中的心跳机制与断线重连详解

    这篇文章主要介绍了Nett中的心跳机制与断线重连详解,我们以客户端发送心跳为例,平时我们的心跳实现方式可能是搞个定时器,定时发送是吧,但是在Netty中却不一样,心跳被称为空闲检测,需要的朋友可以参考下
    2023-12-12
  • Java运算符的知识点与代码汇总

    Java运算符的知识点与代码汇总

    这篇文章主要给大家总结介绍了关于Java运算符知识点与代码的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 使用easyexcel导出的excel文件,使用poi读取时异常处理方案

    使用easyexcel导出的excel文件,使用poi读取时异常处理方案

    这篇文章主要介绍了使用easyexcel导出的excel文件,使用poi读取时异常处理方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • 基于java TCP网络通信的实例详解

    基于java TCP网络通信的实例详解

    本篇文章是对java中TCP网络通信的实例进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • Spring Boot 3整合ShardingSphere-Jdbc分库分表实战

    Spring Boot 3整合ShardingSphere-Jdbc分库分表实战

    本文主要介绍了Spring Boot 3整合ShardingSphere-Jdbc分库分表实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-10-10
  • Java 1.8使用数组实现循环队列

    Java 1.8使用数组实现循环队列

    这篇文章主要为大家详细介绍了Java 1.8使用数组实现循环队列,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-10-10
  • 避免sql注入_动力节点Java学院整理

    避免sql注入_动力节点Java学院整理

    这篇文章主要介绍了避免sql注入,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08

最新评论