Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Use Annotation in Apache Dubbo

DZone 's Guide to

Use Annotation in Apache Dubbo

Learn how to use annotation in Apache Dubbo.

· Integration Zone ·
Free Resource

RPC 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:

Image title

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 class

  • export: 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, @Configurationis a class level annotation that JavaConfig uses as a source of bean definitions. And @Beanis 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 sure com.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
    }
}
  1. Start an embedded zookeeper at port 2181
  2. Initialize an AnnotationConfigApplicationContext instance
  3. Start the Spring Context to serve the service
  4. 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 GreetingServiceas 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 @Referenceannotation under com.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
    }
}
  1. Initiate an AnnotationConfigApplicationContext instance
  2. Start Spring Context
  3. Locate the GreetingServiceConsumer Bean
  4. Call doSayHello by annotation (@Reference)
  5. 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&register.ip=192.168.99.1&remote.timestamp=1533105502086&side=consumer&timestamp=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.

Topics:
java ,distributed architecture ,rpc ,integration ,tutorial ,annotation configuration ,dubbo

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}