Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Principle:Apache Shardingsphere SPI Builder Loading

From Leeroopedia


Knowledge Sources
Domains Cluster_Mode, Distributed_Coordination
Last Updated 2026-02-10 00:00 GMT

Overview

Using the Service Provider Interface (SPI) mechanism to dynamically load and invoke the correct context manager builder enables mode-agnostic bootstrap of a distributed database system.

Description

SPI Builder Loading is the principle of decoupling the bootstrap entry point from any specific mode implementation (Standalone, Cluster, or future modes) by relying on Java's SPI mechanism to discover and instantiate the appropriate ContextManagerBuilder at runtime.

In Apache ShardingSphere, the ContextManagerBuilder interface extends TypedSPI and is annotated with @SingletonSPI. Each mode provides its own implementation:

  • StandaloneContextManagerBuilder -- registered with type "Standalone"
  • ClusterContextManagerBuilder -- registered with type "Cluster"

The bootstrap code never references these concrete classes directly. Instead, it extracts the mode type string from the ModeConfiguration (e.g., "Cluster") and uses TypedSPILoader to locate the matching builder. This pattern provides:

  • Extensibility: New modes can be added by implementing ContextManagerBuilder and registering it via META-INF/services without modifying any existing code.
  • Loose Coupling: The entry point depends only on the ContextManagerBuilder interface, not on any concrete builder class.
  • Configuration-Driven Selection: The mode type string in the user's YAML configuration directly determines which builder is loaded at runtime.
  • Singleton Guarantee: The @SingletonSPI annotation ensures that each builder type is instantiated only once per classloader, avoiding redundant initialization.

The ClusterContextManagerBuilder.build() method orchestrates the entire cluster-mode initialization sequence: it validates and retrieves the cluster repository configuration, initializes the distributed coordination repository, creates the compute node instance context, builds the metadata contexts, registers the node online, and sets up event listeners.

Usage

Use this principle whenever the ShardingSphere bootstrap must select a mode-specific initialization strategy. The entry point (JDBC ShardingSphereDriver or Proxy Bootstrap) reads the mode type from configuration and delegates to the SPI-loaded builder. The builder's build() method returns a fully initialized ContextManager ready for query processing.

Theoretical Basis

The SPI Builder Loading principle combines several design patterns:

1. Strategy Pattern via SPI

The ContextManagerBuilder interface defines a strategy for building a context manager. Concrete implementations provide mode-specific strategies. The SPI mechanism acts as a factory that selects the strategy based on a type key:

FUNCTION bootstrapContextManager(param, eventBusContext):
    modeType = param.getModeConfiguration().getType()
    builder = TypedSPILoader.getService(ContextManagerBuilder.class, modeType)
    RETURN builder.build(param, eventBusContext)

2. Cluster Build Orchestration

When the loaded builder is the Cluster implementation, the build() method performs a specific initialization sequence:

FUNCTION ClusterContextManagerBuilder.build(param, eventBusContext):
    modeConfig = param.getModeConfiguration()
    repositoryConfig = modeConfig.getRepository()  -- cast to ClusterPersistRepositoryConfiguration

    // Step 1: Create compute node instance context
    instanceContext = new ComputeNodeInstanceContext(instance, modeConfig, eventBusContext)

    // Step 2: Initialize cluster persist repository via SPI
    repository = loadAndInitRepository(repositoryConfig, instanceContext)

    // Step 3: Initialize worker ID generator
    instanceContext.init(new ClusterWorkerIdGenerator(repository, instanceId))

    // Step 4: Create metadata contexts from persisted or local configuration
    metaDataContexts = MetaDataContextsFactory.create(param)

    // Step 5: Assemble the context manager
    contextManager = new ContextManager(metaDataContexts, instanceContext, exclusiveEngine, repository)

    // Step 6: Register online and set up event listeners
    registerOnline(instanceContext, param, contextManager)
    registerDeliverEventSubscribers(repository)

    RETURN contextManager

3. Precondition Validation

The cluster builder validates that a non-null ClusterPersistRepositoryConfiguration is present before proceeding. This fail-fast approach prevents obscure errors later in the initialization chain:

FUNCTION getClusterPersistRepository(config, instanceContext):
    PRECONDITION: config IS NOT NULL
        ELSE THROW MissingRequiredClusterRepositoryConfigurationException
    repository = TypedSPILoader.getService(ClusterPersistRepository.class, config.getType())
    repository.init(config, instanceContext)
    RETURN repository

4. Open/Closed Principle

The system is open for extension (new mode builders can be added) but closed for modification (existing bootstrap code does not change when new modes are introduced).

Related Pages

Implemented By

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment