Dubbo的三种使用方式
启动zookeeper
使用的是zookeeper作为注册中心,在运行dubbo项目之前需要启动zookeeper。
xml实现
xml实现是最常使用的一种方式,好处是可以通过配置文件配置注册中心,暴露协议和服务接口,开发人员不需要理会太多Dubbo框架的实现,专注业务逻辑。在公司的项目中使用的也是xml的方式,可以集中管理配置。在github上给出的dubbo-demo有例子。
注解实现
maven的依赖直接使用dubbo-demo的就行,代码实现如下:
Api模块:公共的接口
public interface AnnotationService { public void salHello(String name); }
Provider:服务提供者
服务接口的实现:
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,不然在扫描包的时候会扫描不到。
用注解实现xml的配置。
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注解的类,并进行注册。
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。
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>
查看zookeeper有哪些注册的服务接口
windows启动zkCli.cmd。
ls / 查看根节点下有哪些节点
ls /dubbo 查看dubbo节点下有哪些注册的服务。
参考资料
《深入理解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