Use Annotation in Apache Dubbo
Learn how to use annotation in Apache Dubbo.
Join the DZone community and get the full member experience.
Join For FreeRPC is not particularly a popular subject. There are many reasons for that. However, Apache Dubbo is a popular RPC framework in China. It has been widely adopted and still retains a large user base.
Introduction
Dubbo started as a Java RPC. Since then, it has grown to support multiple languages. Here is the list of its clients.
One of the main reasons behind Dubbo's popularity is because it is battle-hardened in Alibaba's e-commerce platform. As many may despise Java RPC as an old technology, it is actually more efficient than a REST API if done properly.
Dubbo consists of several logical components:
The table below explains the terminology in the diagram:
Provider |
Exposes the endpoint |
Registry |
Service registry and discovery |
Monitor |
Monitoring service |
Consumer |
Consume the provider's service |
Container |
The container where the service runs |
As an enterprise-grade RPC framework, Dubbo is designed and optimized to handle large volumes of requests swiftly. In the meantime, it tries to provide users with an easy-to-use interface. Today, let's take a look at how configuration is done in Dubbo.
Dubbo supports different flavors of configuration. Users can choose between XML, API, or Annotation to configure Dubbo.
Annotation Configuration
In this article, we'll go through an example of how to use annotation configuration in Dubbo.
Here are some of the mostly used annotations:
@EnableDubbo
combines both @EnableDubboConfig
and @DubboComponentScan
. If you don't need to use external configuration registry, you can directly use @DubboComponentScan
to let Dubbo know where to locate the service or consumer.
@Service
is used to configure the Dubbo service.
Some attributes associated with this annotation are:
interfaceClass: Provide the Interface of the class
version: provide the version of the class
group: provide the group of the classexport: expose the service or not
registry: register this service or not
These descriptions will help to better categorize the service in the registry.
@Reference
is used to configure the consumer of the Dubbo service.
Some attributes associated with this annotation are:
interfaceClass: Provide the Interface of the class
version: provide the version of the class
group: provide the group of the class
url: directly call the service with the URL instead of going through the service registry
These additional attributes will help registry to identify and narrow down the service of choice.
Example
Next, let's see how they are used in the code. The following example is from the Dubbo GitHub repo. In the process, we will use Spring java technologies. For example, @Configuration
is a class level annotation that JavaConfig uses as a source of bean definitions. And @Bean
is a method-level annotation that will provide the details of configuration.
1. Define an Interface
We'll define a simple GreetingService
interface, which only has one method sayHello
public interface GreetingService {
String sayHello(String name);
}
2. Declare the Service Class
Implement GreetingService
interface, annotate it with @Service
@Service
public class AnnotatedGreetingService implements GreetingService {
public String sayHello(String name) {
return "hello, " + name;
}
}
3. Add Configuration for the Service
Using Spring Java Config annotation (@Configuration
)and(@EnableDubbo
)to register and configure the service
@Configuration
@EnableDubbo(scanBasePackages = "com.alibaba.dubbo.samples.impl")
static class ProviderConfiguration {
@Bean // #1
public ProviderConfig providerConfig() {
ProviderConfig providerConfig = new ProviderConfig();
providerConfig.setTimeout(1000);
return providerConfig;
}
@Bean // #2
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("dubbo-annotation-provider");
return applicationConfig;
}
@Bean // #3
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setProtocol("zookeeper");
registryConfig.setAddress("localhost");
registryConfig.setPort(2181);
return registryConfig;
}
@Bean // #4
public ProtocolConfig protocolConfig() {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setName("dubbo");
protocolConfig.setPort(20880);
return protocolConfig;
}
}
@EnableDubbo
annotation will make surecom.alibaba.dubbo.samples.impl
will scan all the@Service
annotated classes@Configuration
annotation adds all four@Bean
beans as configuration to the service.
4. Server Side Starts the Service
public class ProviderBootstrap {
public static void main(String[] args) throws Exception {
new EmbeddedZooKeeper(2181, false).start(); // #1
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(ProviderConfiguration.class); // #2
context.start(); // #3
System.in.read(); // #4
}
}
- Start an embedded zookeeper at port 2181
- Initialize an
AnnotationConfigApplicationContext
instance - Start the Spring Context to serve the service
- It's going to be a blocking thread as it is the main thread
Once we run the main
method, the following print out will show that we have registered GreetingService
on zookeeper:
[01/08/18 02:12:51:051 CST] main INFO transport.AbstractServer: [DUBBO] Start NettyServer bind /0.0.0.0:20880, export /192.168.99.1:20880, dubbo version: 2.6.2, current host: 192.168.99.1
[01/08/18 02:12:51:051 CST] main INFO zookeeper.ZookeeperRegistry: [DUBBO] Register: dubbo://192.168.99.1:20880/com.alibaba.dubbo.samples.api.GreetingService?anyhost=true&application=dubbo-annotation-provider&default.timeout=1000&dubbo=2.6.2&generic=false&interface=com.alibaba.dubbo.samples.api
5. Client: Invoke the Service
Use @Reference
to annotate GreetingService
as the remote service
@Component("annotatedConsumer")
public class GreetingServiceConsumer {
@Reference
private GreetingService greetingService;
public String doSayHello(String name) {
return greetingService.sayHello(name);
}
}
6. Client Adds Configuration
@Configuration
@EnableDubbo(scanBasePackages = "com.alibaba.dubbo.samples.action")
@ComponentScan(value = {"com.alibaba.dubbo.samples.action"})
static class ConsumerConfiguration {
@Bean // #1
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("dubbo-annotation-consumer");
return applicationConfig;
}
@Bean // #2
public ConsumerConfig consumerConfig() {
ConsumerConfig consumerConfig = new ConsumerConfig();
consumerConfig.setTimeout(3000);
return consumerConfig;
}
@Bean // #3
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setProtocol("zookeeper");
registryConfig.setAddress("localhost");
registryConfig.setPort(2181);
return registryConfig;
}
}
@EnableDubbo
will ensure all the classes with@Reference
annotation undercom.alibaba.dubbo.samples.impl
will be scanned.- Use
@Configuration
with Java Config to add all three@Bean
configurations to the consumer.
7. Client Invokes the Service
public class ConsumerBootstrap {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class); // #1
context.start(); // #2
GreetingServiceConsumer greetingServiceConsumer = context.getBean(GreetingServiceConsumer.class); // #3
String hello = greetingServiceConsumer.doSayHello("annotation"); // #4
System.out.println("result: " + hello); // #5
}
}
- Initiate an
AnnotationConfigApplicationContext
instance - Start Spring Context
- Locate the
GreetingServiceConsumer
Bean - Call
doSayHello
by annotation (@Reference
) - Print out the result
Here is the sample print out:
[01/08/18 02:38:40:040 CST] main INFO config.AbstractConfig: [DUBBO] Refer dubbo service com.alibaba.dubbo.samples.api.GreetingService from url zookeeper://localhost:2181/com.alibaba.dubbo.registry.RegistryService?anyhost=true&application=dubbo-annotation-consumer&check=false&default.timeout=3000&dubbo=2.6.2&generic=false&interface=com.alibaba.dubbo.samples.api.GreetingService&methods=sayHello&pid=33001®ister.ip=192.168.99.1&remote.timestamp=1533105502086&side=consumer×tamp=1533105519216, dubbo version: 2.6.2, current host: 192.168.99.1
[01/08/18 02:38:40:040 CST] main INFO annotation.ReferenceBeanBuilder: <dubbo:reference object="com.alibaba.dubbo.common.bytecode.proxy0@673be18f" singleton="true" interface="com.alibaba.dubbo.samples.api.GreetingService" uniqueServiceName="com.alibaba.dubbo.samples.api.GreetingService" generic="false" id="com.alibaba.dubbo.samples.api.GreetingService" /> has been built.
result: hello, annotation
Summary
This is a detailed example of how Dubbo works using annotation and Spring boot. Dubbo has many other interesting features. We'll introduce more of them in future articles.
Opinions expressed by DZone contributors are their own.
Comments