Backend Development 9 min read

Dynamic Service Provider Switching with spring-smart-di and AutowiredProxySPI

This article explains how to dynamically switch between multiple service providers, such as SMS vendors, in a Spring‑based backend by using spring‑smart‑di's @AutowiredProxySPI and related annotations, covering configuration, Maven dependency, enabling the feature, and custom proxy implementations.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Dynamic Service Provider Switching with spring-smart-di and AutowiredProxySPI

In many backend systems a single feature must integrate with multiple service providers to improve fault tolerance and control costs, requiring the ability to switch providers at runtime.

The traditional method creates separate implementation classes for each provider and stores the active provider's identifier in a configuration source (e.g., a database or Nacos). Each request reads the identifier and manually retrieves the corresponding bean.

Using an SMS service as an example, the manual steps are:

1. Add a configuration entry such as sms.impl = "SomeSms" .

2. In the sending code, read sms.impl , obtain the bean name, and invoke the service. The pseudo‑code is:

void sendSmsTouser(Req req) {
    // 1. Get current provider name
    String name = get("sms.impl");
    // 2. Get the implementation bean
    SmsService smsService = springContext.getBean(name);
    // 3. Execute business logic
    smsService.sendMsg(req);
}

This approach is cumbersome because the configuration must be read and the bean loaded on every call.

spring‑smart‑di introduces @AutowiredProxySPI , which lets Spring automatically inject the appropriate implementation based on the configuration and update the injection when the configuration changes.

spring‑smart‑di Overview

spring‑smart‑di extends the standard @Autowired mechanism with two new annotations: @SmartAutowired and @AutowiredProxySPI . The article focuses on using @AutowiredProxySPI for dynamic provider switching.

Quick Start

1. Add the Maven dependency:

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

2. Enable the feature on a Spring configuration class with @EnableSmartDI .

3. Use @EnvironmentProxySPI to declare a configuration point that supplies the provider name, e.g.:

@EnvironmentProxySPI("${sms.impl}")
public interface SmsService {}

4. Implement the providers and give them aliases:

@BeanAliasName("SomeSms Service")
@Component
public class ASmsService implements SmsService {}

@BeanAliasName("OtherSms Service")
@Component
public class BSmsService implements SmsService {}

5. Configure the active provider in application.yml (or Nacos):

sms:
  impl: OtherSms Service

6. Inject the service with @AutowiredProxySPI just like a normal @Autowired :

// Dependency injection
@AutowiredProxySPI
private SmsService smsService;

Changing the ${sms.impl} value updates the injected proxy at runtime, so the new implementation is used without restarting the application.

Custom Configuration Points

For non‑environment sources (e.g., a database), define a custom annotation such as @DBProxySPI that is meta‑annotated with @ProxySPI and points to a factory class implementing AnnotationProxyFactory . The factory reads the configuration from the database and returns the appropriate bean.

@Inherited
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@ProxySPI(DbProxyFactory.class) // specify logic
public @interface DBProxySPI {
    String value();
}

public class DbProxyFactory implements AnnotationProxyFactory
{
    @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}")
public interface SmsService {}

These steps demonstrate a clean, efficient way to achieve dynamic service provider switching in a Spring backend.

Promotional Note

The author also advertises a booklet covering many enterprise‑level backend topics such as JVM tuning, database optimization, and API design, priced at 199 CNY (discounted to 11.9 CNY).

backendJavaMicroservicesSpringdynamic configurationdependency injectionspring-smart-di
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.