Dubbo的三種使用方式

啓動zookeeper

使用的是zookeeper做爲註冊中心,在運行dubbo項目以前須要啓動zookeeper。html

xml實現

xml實現是最常使用的一種方式,好處是能夠經過配置文件配置註冊中心,暴露協議和服務接口,開發人員不須要理會太多Dubbo框架的實現,專一業務邏輯。在公司的項目中使用的也是xml的方式,能夠集中管理配置。在github上給出的dubbo-demo有例子。java

github上的Dubbo項目git

註解實現

maven的依賴直接使用dubbo-demo的就行,代碼實現以下:github

Api模塊:公共的接口

public interface AnnotationService {

    public void salHello(String name);

}

Provider:服務提供者

服務接口的實現:spring

import gdut.ff.api.AnnotationService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Component;

import gdut.ff.api.AnnotationService;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.rpc.RpcContext;

@Service
public class AnnotationServiceImpl implements AnnotationService {

    public void salHello(String name) {
        System.out.println(name + " from" + RpcContext.getContext().getRemoteAddress());
    }

}

注意這裏的@Service註解是org.apache.dubbo.config.annotation.Service,否則在掃描包的時候會掃描不到。apache

用註解實現xml的配置。windows

import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.ProviderConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableDubbo(scanBasePackages = "gdut.ff.provider")
public class ProviderConfiguration   {

    @Bean
    public ProviderConfig providerConfig() {
        return new ProviderConfig();
    }

    @Bean
    public ApplicationConfig applicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("annotation-provider");
        return applicationConfig;
    }

    //配置Zookeeper註冊中心
    @Bean
    public RegistryConfig registryConfig() {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setProtocol("zookeeper");
        registryConfig.setAddress("127.0.0.1");
        registryConfig.setPort(2181);
        return registryConfig;
    }

    //使用Dubbo協議,20880端口監聽服務
    @Bean
    public ProtocolConfig protocolConfig() {
        ProtocolConfig protocolConfig = new ProtocolConfig();
        protocolConfig.setName("dubbo");
        protocolConfig.setPort(20880);
        return protocolConfig;
    }

}

啓動的時候,會調用ProviderConfiguration類,根據配置的scanBasePackages掃描對應包下的帶有@Service註解的類,並進行註冊。api

public class AnnotationProviderMain {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class);
        context.start();
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

(3)Consumer:服務消費者

消費者對服務接口的實現,是調用提供者的實現。這裏是在一個實例AnnotationServiceImpl中用@Reference引用了api的接口AnnotationService,真正調用的時候注入的是服務提供者註冊的一個AnnotationService實例。@Reference至關於Spring的@Autowired和@Resource。app

import gdut.ff.api.AnnotationService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Component;

@Component
public class AnnotationServiceImpl {

    @Reference
    private AnnotationService annotationService;

    public void sayHello(String name) {
        annotationService.salHello(name);
    }

}

消費者的配置框架

import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ConsumerConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
//指定要掃描的消費註解,會觸發注入
@EnableDubbo(scanBasePackages = "gdut.ff.consumer")
@ComponentScan(value = {"gdut.ff.consumer"})
public class ConsumerConfiguration {

    @Bean
    public ApplicationConfig applicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("annotation-consumer");
        return applicationConfig;
    }

    @Bean
    public ConsumerConfig consumerConfig() {
        return new ConsumerConfig();
    }

    @Bean
    public RegistryConfig registryConfig() {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setProtocol("zookeeper");
        registryConfig.setAddress("127.0.0.1");
        registryConfig.setPort(2181);
        return registryConfig;
    }
}

啓動

public class AnnotationConsumerMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class);
        context.start();
        //獲取一個Bean實例
        AnnotationServiceImpl bean = context.getBean(AnnotationServiceImpl.class);
        bean.sayHello("liufeifei");
    }

}

API實現

maven的依賴直接使用dubbo-demo的就行,代碼實現以下:

Provider:服務提供者

public class ApiProviderMain {

    public static void main(String[] args) {
        ServiceConfig<AnnotationService> service = new ServiceConfig<AnnotationService>();
        service.setApplication(new ApplicationConfig("api-provider"));
        service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
        //指定暴露的接口
        service.setInterface(AnnotationService.class);
        //這裏是直接用new一個對象來進行實例化
        service.setRef(new AnnotationServiceImpl());
        //暴露服務
        service.export();
        System.out.println("java api-provider is running");
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Consumer:服務消費者

public class ApiConsumerMain {

    public static void main(String[] args) {
        ReferenceConfig<AnnotationService> annotationServiceReferenceConfig = new ReferenceConfig<AnnotationService>();
        annotationServiceReferenceConfig.setApplication(new ApplicationConfig("api-consumer"));
        annotationServiceReferenceConfig.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
        //指定要消費的服務接口
        annotationServiceReferenceConfig.setInterface(AnnotationService.class);
        //建立遠程鏈接並作動態代理轉換
        AnnotationService annotationService = annotationServiceReferenceConfig.get();
        annotationService.salHello("liufeifei");
    }
}

使用mvn exec:java運行maven項目

在pom.xml文件中添加exec-maven-plugin插件,並指定執行的main方法。

<build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>gdut.ff.consumer.ApiConsumerMain</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

clipboard.png

查看zookeeper有哪些註冊的服務接口

windows啓動zkCli.cmd。
ls / 查看根節點下有哪些節點
ls /dubbo 查看dubbo節點下有哪些註冊的服務。
clipboard.png

參考資料

《深刻理解Apache Dubbo與實戰》
java.lang.IllegalStateException: KeeperErrorCode = ConnectionLoss for /dubbo問題解決
@Service註解的坑
Maven統一聲明版本號
查看zookeeper註冊中心是否有註冊服務
mvn編譯java project: Failed to execute goal org.codehaus.mojo:exec-maven-plugin

相關文章
相關標籤/搜索