Spring-Smart-DI 动态切换实现类,很不错!

在系统开发的实际场景中,我们常常会碰到这样一类需求:同一个功能需要对接多个服务提供商。 这么做主要基于两个重要原因。 其一,为了规避某个服务商的服务出现不可用的风险,以便在出现问题时能够迅速切换到其他服务商,确保系统的稳定性和业务的连续性;其二,不同服务商的收费标准存在差异,从成本控制的角度出发,需要根据实际情况进行灵活切换。

在系统开发的实际场景中,我们常常会碰到这样一类需求:同一个功能需要对接多个服务提供商。这么做主要基于两个重要原因。其一,为了规避某个服务商的服务出现不可用的风险,以便在出现问题时能够迅速切换到其他服务商,确保系统的稳定性和业务的连续性;其二,不同服务商的收费标准存在差异,从成本控制的角度出发,需要根据实际情况进行灵活切换。

传统的快速切换逻辑实现方法是,先为每个服务商编写对应的实现类,然后在配置点(这个配置点可以是数据库,也可以是像 Nacos 这样的配置中心)配置当前正在使用的服务商。在每次执行相关业务逻辑时,都要从配置点获取当前使用的服务商信息,再去执行该服务商对应的业务逻辑。

以系统接入多个短信服务商为例,用户可以根据自身需求动态地在不同服务商之间进行切换。下面我们详细看看如果手动实现这个功能,具体步骤是怎样的。

第一步,在某个配置位置(例如 Nacos 或者数据库)配置当前使用的服务商对应的标识值。比如,我们设置 sms.impl = "某腾短信"。

第二步,在代码中执行发短信操作时,手动获取 sms.impl 对应的服务商实现类。以下是相应的伪代码示例:

复制
void sendSmsTouser(Req req) {
    // 1、获取当前使用的服务商
    String name = get("sms.impl");
    // 2、获取对应的实现类
    SmsService smsService = springContext.getBean(name);
    // 3、使用 smsService 执行具体业务逻辑
    smsService.sendMsg(req);
}

不过,这种实现方式存在明显的弊端,它比较繁琐,每次执行都需要手动去获取配置并加载对应的实现类。那么,有没有一种更优雅的方式,让 Spring 的 @Autowired 注解在注入时能够自动根据配置点的配置去注入对应的实现类,并且当配置发生变化时,注入的实现类也能自动更新呢?spring-smart-di 的 AutowiredProxySPI 就是为解决这个问题而精心设计的。

1. spring-smart-di 简介

spring-smart-di 是对 Spring @Autowired 注解的一次创新性扩展,它为用户提供了自定义 Autowired 注入逻辑的能力。目前,它实现了两个非常重要的注解:@SmartAutowired 和 @AutowiredProxySPI。在本文中,我们将重点聚焦于如何使用 AutowiredProxySPI 来实现动态切换服务提供商的功能。

假设我们的系统对接了多个短信服务商,下面我们通过一个快速上手的案例,详细了解如何使用 AutowiredProxySPI 来实现动态切换。

2、快速开始

2.1 引入依赖

首先,我们需要在项目中引入 spring-smart-di 的依赖。在 Maven 项目的 pom.xml 文件中添加以下依赖代码:

复制
<dependency>
    <groupId>io.github.burukeyou</groupId>
    <artifactId>spring-smart-di-all</artifactId>
    <version>0.2.0</version>
</dependency>

2.2 启用功能

在 Spring 配置类上标记 @EnableSmartDI 注解,以此来启用 spring-smart-di 的强大功能。

2.3 @EnvironmentProxySPI 注解的使用

@EnvironmentProxySPI 注解代表着一个配置点,其主要作用是配置如何获取具体实现类的逻辑。

假设我们的系统中有两个短信服务商,需要实现动态切换。我们需要在接口上配置 @EnvironmentProxySPI 注解,表示从环境变量配置点中获取当前使用的服务商。这里我们将配置信息存储在属性 ${sms.impl} 中。

复制
@EnvironmentProxySPI("${sms.impl}")
publicinterface SmsService {
}

// 给实现类定义别名
@BeanAliasName("某腾短信服务")
@Component
publicclass ASmsService implements SmsService {
}

@BeanAliasName("某移短信服务")
@Component
publicclass BSmsService implements SmsService {
}

2.4 配置当前使用的服务商

我们可以在配置文件中配置当前使用的服务商。配置的值可以是 @BeanAliasName 注解指定的值,也可以是 @Component 注解指定的值,还可以是具体的全路径类名。

复制
sms:
  impl: 某移短信服务

2.5 @AutowiredProxySPI 注入使用

接下来,我们只需要像使用 @Autowired 注解一样使用 @AutowiredProxySPI 注解即可。

复制
// 依赖注入
@AutowiredProxySPI
private SmsService smsService;

通过以上步骤,我们就成功完成了动态切换服务提供商的需求。只要我们改变配置属性 ${sms.impl} 的值,系统就会实时生效,而无需重启服务。这是因为 @AutowiredProxySPI 注入的是一个代理对象,每次执行时会先实时获取当前使用的实现类,然后再执行调用操作。并且,在使用上与直接使用 @Autowired 注解基本没有区别。

2.6 定义不同的配置点

@EnvironmentProxySPI 注解主要用于配置环境变量相关的配置点。如果我们想要自定义配置,例如从数据库中获取配置信息,可以实现自己的 ProxySPI 注解。

下面是一个自定义 DBProxySPI 注解的示例,我们需要标记上 @ProxySPI 注解,并指定具体的配置获取逻辑实现类 AnnotationProxyFactory。

复制
@Inherited
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@ProxySPI(DbProxyFactory.class) // 指定配置获取逻辑
public @interface DBProxySPI {
    String value();
}

@Component
publicclass DbProxyFactory implements AnnotationProxyFactory<DBProxySPI> {
    @Autowired
    private SysConfigMapper sysConfigDao;

    @Override
    public Object getProxy(Class<?> targetClass, DBProxySPI spi) {
        // 根据注解从数据库获取要注入的实现类
        String configName = sysConfigDao.getConfig(spi.value());
        return springContext.getBean(configName);
    }
}

@DBProxySPI("${sms.impl}")
publicinterface SmsService {
}

通过以上的步骤,我们就可以灵活地实现动态切换服务提供商的功能,并且可以根据不同的需求自定义配置获取逻辑。spring-smart-di 为我们提供了一种简洁、高效的方式来处理这种动态切换的场景,让我们的代码更加灵活和易于维护。

相关资讯

Deepseek4j再更新:Java应用一行代码集成DeepSeek

deepseek4j 是什么deepseek4j() 是一个专为 Java 开发者打造的 DeepSeek 模型集成框架。 通过优雅的 API 设计,只需一行代码,即可实现接入 DeepSeek,并获得以下核心能力:完整思维链保留:完美保留 DeepSeek 模型的推理过程,让 AI 的思考过程可追溯流式输出体验:基于 Reactor 实现的流式响应,带来类 ChatGPT 的打字机效果复制使用 deepseek4j,您可以专注于业务逻辑开发,而无需关心底层细节。 一、v1.3 更新内容1.1 联网搜索支持1739118403新版本最重要的更新是引入了联网搜索能力,这一功能带来三个关键优势:突破时间边界:模型不再受限于预训练数据的时间范围,可以获取和处理最新信息实时信息获取:通过高质量信息源获取实时资讯,提供更精准的问答服务差异化竞争:在大模型同质化严重的当下,联网搜索成为关键的差异化竞争点复制1.2 智能系统提示词1739118117系统提示词(System Prompt)是基于模型开发的应用程序内置的指令,让决定了模型在特定上下文中的表现方式、回答风格和功能范围。

Spring 宣布接入 DeepSeek

DeepSeek 是深度求索公司发布的大模型,是国产之光。 大家应该学会如何使用 DeepSeek 大模型,下面我们将看下如何开发基于 DeepSeek 大模型的智能应用。 DeepSeek 大模型DeepSeek 推出两款模型;DeepSeek V 系列,对于V系列主要 对话,模型名称:deepseek-chatDeepSeek R 系统,对于R系统主要 推理, 模型名称:deepseek-reasonerDeepSeek 官方更新日志,可以看到模型发布和演化的过程。

重磅开源!基于 Spring Boot 的企业级 DeepSeek 知识库与智能对话方案

本项目基于 Spring Boot 3.4 构建,旨在打造一款高效、智能的企业级知识库与智能对话平台,充分集成 DeepSeek 大语言模型,以支持企业级私有化部署和智能客服应用。 项目目标该方案通过整合 DeepSeek 强大的自然语言处理能力,实现高效、精准的对话交互,同时支持企业知识库的管理,助力企业构建智能化的客户支持与内部知识共享体系。 技术架构后端基于 Spring Boot 3.4 开发,提供 RESTful API 以处理业务逻辑,并与 DeepSeek 模型进行高效交互。