
在Spring框架中自动装配(Auto-wiring)是Spring容器自动将对象注入到其他对象中以减少手动配置的需求。当你使用MapString, T类型的依赖时Spring提供了几种特殊的方式来自动装配这些Map类型的bean1. 为什么能自动收集所有子类Autowired private MapString, OssLogic ossLogicMap;这是 Spring 的一个内置特性当注入目标类型为 MapString, T 时Spring 会把容器中所有的 T 类型及其子类Bean 全部收集进这个 Mapkey 是 bean 名称value 是对应的 Bean 实例。所以这里并不需要手动一个个注册。只要某个类满足是 OssLogic / BaseLogic 的子类或本身被 Spring 管理为 Bean项目里用 Configuration 标注等价于 Component例如 BjlhOssLogic extends OssLogicConfiguration它们都会被自动装进对应的 Map。2. bean 名称的命名约定bean 名称由类名首字母小写得到例如BjlhOssLogic → beanName bjlhOssLogicinit() 启动时按命名约定从 beanName 反推 vendorCode3.运行时如何分发注册完成后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 启动时会自动把它收进 Mapinit() 自动完成注册。完整代码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 MapString, 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 MapString, OssLogic ossLogicMap; private final MapString, OssLogic vendorOssLogicCache new HashMap(); PostConstruct public void init() { // 注册 OssLogic 映射 if (ossLogicMap ! null) { for (Map.EntryString, 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); } }