XML-based configuration remains a practical approach for managing Apache Dubbo RPC endpoints, particularly when decoupling infrastructure settings from application source code. This methodology facilitates environment-specific overrides, centralized version control, and clearer depandency mapping for complex deployments.
Dependency Initialization
Prior to configuration, ensure the project includes the necessary runtime libraries. The following Maven declarations establish the core Dubbo engine, Zookeeper registry client, and Spring framework integration:
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.15</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>2.7.15</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.23</version>
</dependency>
</dependencies>
Provider Side Configuration
Define the remote interface and its concrete implementation first. These classes remain unaware of Dubbo specifics until wired into the container.
public interface AccountService {
String fetchAccountDetails(String identifier);
}
public class AccountServiceImpl implements AccountService {
@Override
public String fetchAccountDetails(String identifier) {
return String.format("Profile loaded for ID: %s", identifier);
}
}
Create a dedicated Spring configuration file (dubbo-provider.xml) to declare registry targets, network protocols, and service bindings:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo
https://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:registry address="zookeeper://localhost:2181" />
<dubbo:protocol name="dubbo" port="20880" server="netty4" />
<dubbo:service interface="com.app.api.AccountService"
ref="accountEndpoint"
version="2.0.1" />
<bean id="accountEndpoint" class="com.app.impl.AccountServiceImpl" />
</beans>
Key directives:
<dubbo:registry>directs traffic to the discovery backend.<dubbo:protocol>binds the listening socket and transport layer.<dubbo:service>registers the contract and maps it to the instantiated bean.
Consumer Side Configuraton
The consuming module requires a reference proxy rather than an actual implementation. Business logic interacts solely through the interface.
public class BillingManager {
private AccountService accountService;
public void setAccountService(AccountService accountService) {
this.accountService = accountService;
}
public void processTransaction(String accountId) {
String details = accountService.fetchAccountDetails(accountId);
System.out.println("Billing step resolved: " + details);
}
}
Map the remote reference within dubbo-consumer.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo
https://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:registry address="zookeeper://localhost:2181" />
<dubbo:reference id="accountProxy"
interface="com.app.api.AccountService"
version="2.0.1"
check="false" />
<bean id="billingController" class="com.app.client.BillingManager">
<property name="accountService" ref="accountProxy" />
</bean>
</beans>
Notice how <dubbo:reference> generates a dynamic proxy. Property injection into BillingManager bridges the container-managed proxy with application logic.
Runtime Execution
Bootstrapping follows standard Spring initialization patterns for XML-backed contexts.
Provider launch routine:
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ServerBootstrapper {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("dubbo-provider.xml");
ctx.start();
System.in.read(); // Keep JVM alive
}
}
Consumer execution flow:
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ClientRunner {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("dubbo-consumer.xml");
BillingManager manager = ctx.getBean(BillingManager.class);
manager.processTransaction("TXN-9981");
}
}
Upon initialization, the provider broadcasts its endpoint metadata to Zookeeper. The consumer discovers the location, establishes connection pools, and routes invocations transparently across the network boundary.