本文讲解了Dubbo的几种配置方式,包括XML、API以及Annotation的方式;Dubbo版本基于2.x;
源代码:
Dubbo的几种配置方式总结 XML方式 XML 方式和 Spring 框架中的 XML 配置方式一模一样;
接口实现 io/github/jasonkayzk/impl/BasicHelloServiceImpl.java
1 2 3 4 5 6 7 8 9 public class BasicHelloServiceImpl implements HelloService { @Override public String sayHello (String name) { System.out.println("[" + new SimpleDateFormat ("HH:mm:ss" ).format(new Date ()) + "] Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress()); return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress(); } }
Provider实现 io/github/jasonkayzk/XmlProviderBootstrap.java
1 2 3 4 5 6 7 8 9 10 11 public class XmlProviderBootstrap { public static void main (String[] args) throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext ( new String []{"spring/dubbo-demo-provider.xml" }); context.start(); System.in.read(); } }
上面的代码读取了 resources 下的配置:
spring/dubbo-demo-provider.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo ="http://dubbo.apache.org/schema/dubbo" xmlns ="http://www.springframework.org/schema/beans" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd" > <dubbo:application name ="demo-provider" /> <dubbo:registry group ="aaa" address ="zookeeper://127.0.0.1:2181" /> <dubbo:registry address ="zookeeper://127.0.0.1:2181" /> <dubbo:protocol name ="dubbo" port ="20890" /> <bean id ="helloService" class ="io.github.jasonkayzk.impl.BasicHelloServiceImpl" /> <dubbo:service interface ="io.github.jasonkayzk.HelloService" ref ="helloService" /> </beans >
Consumer配置 Consumer实现:
io/github/jasonkayzk/XmlConsumerBootstrap.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class XmlConsumerBootstrap { public static void main (String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext ( new String []{"spring/dubbo-demo-consumer.xml" }); context.start(); HelloService helloService = (HelloService) context.getBean("demoService" ); while (true ) { try { Thread.sleep(1000 ); String hello = helloService.sayHello("world" ); System.out.println(hello); } catch (Throwable throwable) { throwable.printStackTrace(); } } } }
配置:
spring/dubbo-demo-consumer.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo ="http://dubbo.apache.org/schema/dubbo" xmlns ="http://www.springframework.org/schema/beans" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd" > <dubbo:application name ="demo-consumer" /> <dubbo:registry group ="aaa" address ="zookeeper://127.0.0.1:2181" /> <dubbo:reference id ="demoService" check ="false" interface ="io.github.jasonkayzk.HelloService" /> </beans >
API方式 如果不想编写 XML,可以使用API的方式进行配置:
Provider实现 Provider实现如下:
dubbo2/b-hello-dubbo-api/src/main/java/io/github/jasonkayzk/ApiProviderBootstrap.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class ApiProviderBootstrap { public static void main (String[] args) throws Exception { HelloService helloService = new ApiHelloServiceImpl (); ApplicationConfig application = new ApplicationConfig (); application.setName("api-hello-provider" ); RegistryConfig registry = new RegistryConfig (); registry.setAddress("zookeeper://127.0.0.1:2181" ); ProtocolConfig protocol = new ProtocolConfig (); protocol.setName("dubbo" ); protocol.setPort(12345 ); protocol.setThreads(20 ); ServiceConfig <HelloService> service = new ServiceConfig <>(); service.setApplication(application); service.setRegistry(registry); service.setProtocol(protocol); service.setInterface(HelloService.class); service.setRef(helloService); service.setVersion("1.0.0" ); service.export(); System.in.read(); } }
Consumer实现 dubbo2/b-hello-dubbo-api/src/main/java/io/github/jasonkayzk/ApiConsumerBootstrap.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class ApiConsumerBootstrap { public static void main (String[] args) { ApplicationConfig application = new ApplicationConfig (); application.setName("api-hello-consumer" ); RegistryConfig registry = new RegistryConfig (); registry.setAddress("zookeeper://127.0.0.1:2181" ); ReferenceConfig <HelloService> reference = new ReferenceConfig <>(); reference.setApplication(application); reference.setRegistry(registry); reference.setInterface(HelloService.class); reference.setVersion("1.0.0" ); HelloService helloService = reference.get(); while (true ) { try { Thread.sleep(1000 ); String hello = helloService.sayHello("world" ); System.out.println(hello); } catch (Throwable throwable) { throwable.printStackTrace(); } } } }
Annotation方式 接口实现 Provider中接口实现: dubbo2/c-hello-dubbo-annotation/src/main/java/io/github/jasonkayzk/provider/impl/AnnotationHelloServiceImpl.java
1 2 3 4 5 6 7 8 9 10 @Service public class AnnotationHelloServiceImpl implements HelloService { @Override public String sayHello (String name) { System.out.println("[" + new SimpleDateFormat ("HH:mm:ss" ).format(new Date ()) + "] Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress()); return "Hello " + name + ", response from annotation-provider: " + RpcContext.getContext().getLocalAddress(); } }
使用了 @Service 注解;
Consumer中Action声明 使用注解方式需要在 Consumer 中声明接口,从而将具体的实现注入;:
dubbo2/c-hello-dubbo-annotation/src/main/java/io/github/jasonkayzk/consumer/action/AnnotationHelloAction.java
1 2 3 4 5 6 7 8 9 10 11 @Component("annotationHelloAction") public class AnnotationHelloAction { @Reference private HelloService helloService; public String doSayHello (String name) { return helloService.sayHello(name); } }
Annotation中使用Property配置 Provider的配置及启动 Property配置如下:
dubbo2/c-hello-dubbo-annotation/src/main/resources/spring/dubbo-provider.properties
1 2 3 4 dubbo.application.name =annotation-configuration-provider dubbo.registry.address =zookeeper://127.0.0.1:2181 dubbo.protocol.name =dubbo dubbo.protocol.port =20880
启动实现:
dubbo2/c-hello-dubbo-annotation/src/main/java/io/github/jasonkayzk/provider/AnnotationPropertyProviderBootstrap.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @Configuration @EnableDubbo(scanBasePackages = "io.github.jasonkayzk.consumer.action") @ComponentScan(value = {"io.github.jasonkayzk.consumer.action"}) @PropertySource("classpath:/spring/dubbo-consumer.properties") class AnnotationPropertyConsumerConfiguration {} public class AnnotationPropertyConsumerBootstrap { public static void main (String[] args) throws InterruptedException { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext (AnnotationPropertyConsumerConfiguration.class); context.start(); AnnotationHelloAction helloService = context.getBean(AnnotationHelloAction.class); for (int i = 0 ; i < 10 ; i++) { String hello = helloService.doSayHello("annotation-config" ); System.out.println("result: " + hello); Thread.sleep(1000 ); } } }
Consumer的配置及启动 Property配置如下:
dubbo2/c-hello-dubbo-annotation/src/main/resources/spring/dubbo-consumer.properties
1 2 3 dubbo.application.name =annotation-configuration-consumer dubbo.registry.address =zookeeper://127.0.0.1:2181 dubbo.consumer.timeout =3000
启动如下:
dubbo2/c-hello-dubbo-annotation/src/main/java/io/github/jasonkayzk/consumer/AnnotationPropertyConsumerBootstrap.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Configuration @EnableDubbo(scanBasePackages = "io.github.jasonkayzk.consumer.action") @ComponentScan(value = {"io.github.jasonkayzk.consumer.action"}) @PropertySource("classpath:/spring/dubbo-consumer.properties") class AnnotationPropertyConsumerConfiguration {} public class AnnotationPropertyConsumerBootstrap { public static void main (String[] args) throws InterruptedException { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext (AnnotationPropertyConsumerConfiguration.class); context.start(); AnnotationHelloAction helloService = context.getBean(AnnotationHelloAction.class); for (int i = 0 ; i < 10 ; i++) { String hello = helloService.doSayHello("annotation-config" ); System.out.println("result: " + hello); Thread.sleep(1000 ); } } }
使用SpringBean注入 除了从 Property 中配置,还可以使用 Spring Bean 注入的方式来进行配置;
Provider配置 dubbo2/c-hello-dubbo-annotation/src/main/java/io/github/jasonkayzk/AnnotationProviderBootstrap.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 @Configuration @EnableDubbo(scanBasePackages = "io.github.jasonkayzk.provider.impl") class ProviderConfiguration { @Bean public ProviderConfig providerConfig () { ProviderConfig providerConfig = new ProviderConfig (); providerConfig.setTimeout(1000 ); return providerConfig; } @Bean public ApplicationConfig applicationConfig () { ApplicationConfig applicationConfig = new ApplicationConfig (); applicationConfig.setName("dubbo-annotation-provider" ); return applicationConfig; } @Bean public RegistryConfig registryConfig () { RegistryConfig registryConfig = new RegistryConfig (); registryConfig.setProtocol("zookeeper" ); registryConfig.setAddress("localhost" ); registryConfig.setPort(2181 ); return registryConfig; } @Bean public ProtocolConfig protocolConfig () { ProtocolConfig protocolConfig = new ProtocolConfig (); protocolConfig.setName("dubbo" ); protocolConfig.setPort(20880 ); return protocolConfig; } } public class AnnotationProviderBootstrap { public static void main (String[] args) throws IOException { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext (ProviderConfiguration.class); context.start(); System.in.read(); } }
Consumer配置 dubbo2/c-hello-dubbo-annotation/src/main/java/io/github/jasonkayzk/AnnotationConsumerBootstrap.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 @Configuration @EnableDubbo(scanBasePackages = "io.github.jasonkayzk.consumer.action") @ComponentScan(value = {"io.github.jasonkayzk.consumer.action"}) class ConsumerConfiguration { @Bean public ApplicationConfig applicationConfig () { ApplicationConfig applicationConfig = new ApplicationConfig (); applicationConfig.setName("dubbo-annotation" ); return applicationConfig; } @Bean public ConsumerConfig consumerConfig () { ConsumerConfig consumerConfig = new ConsumerConfig (); consumerConfig.setTimeout(3000 ); return consumerConfig; } @Bean public RegistryConfig registryConfig () { RegistryConfig registryConfig = new RegistryConfig (); registryConfig.setProtocol("zookeeper" ); registryConfig.setAddress("localhost" ); registryConfig.setPort(2181 ); return registryConfig; } } public class AnnotationConsumerBootstrap { public static void main (String[] args) throws InterruptedException { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext (ConsumerConfiguration.class); ctx.start(); AnnotationHelloAction greetingServiceConsumer = ctx.getBean(AnnotationHelloAction.class); for (int i = 0 ; i < 10 ; i++) { String hello = greetingServiceConsumer.doSayHello("annotation-config" ); System.out.println("result: " + hello); Thread.sleep(1000 ); } } }
使用YAML配置 上面的配置主要是通过 XML 或者 Property 的方式,实际上阅读起来并没有那么容易;
比较高版本的 SpringBoot 中可以使用 YAML 的方式进行配置;
YAML配置转换工厂类 创建一个工厂类用于将YAML配置转为Property配置:
dubbo2/d-hello-dubbo-yaml/src/main/java/io/github/jasonkayzk/utils/YamlPropertySourceFactory.java
1 2 3 4 5 6 7 8 public class YamlPropertySourceFactory extends DefaultPropertySourceFactory { @Override public PropertySource <?> createPropertySource (String name, EncodedResource resource) throws IOException { List <PropertySource<?>> sources = new YamlPropertySourceLoader ().load(resource.getResource().getFilename(),resource.getResource()); return sources.get(0 ); } }
Provider配置 使用 YAML 配置 Provider:
dubbo2/d-hello-dubbo-yaml/src/main/resources/dubbo-provider.yml
1 2 3 4 5 6 7 8 dubbo: application: name: "yaml-configuration-provider" registry: address: "zookeeper://127.0.0.1:2181" protocol: name: "dubbo" port: "20880"
配置 Bean 代码:
dubbo2/d-hello-dubbo-yaml/src/main/java/io/github/jasonkayzk/provider/config/YamlConfigProviderConfig.java
1 2 3 4 5 @Configuration @EnableDubbo(scanBasePackages = "io.github.jasonkayzk.provider.impl") @PropertySource(value = "classpath:dubbo-provider.yml", factory = YamlPropertySourceFactory.class) public class YamlConfigProviderConfig {}
Consumer配置 YAML 配置:
dubbo2/d-hello-dubbo-yaml/src/main/resources/dubbo-consumer.yml
1 2 3 4 5 6 7 dubbo: application: name: "yaml-configuration-consumer" registry: address: "zookeeper://127.0.0.1:2181" consumer: timeout: 3000
配置 Bean 代码:
dubbo2/d-hello-dubbo-yaml/src/main/java/io/github/jasonkayzk/consumer/config/YamlConfigConsumerConfig.java
1 2 3 4 5 6 @Configuration @EnableDubbo(scanBasePackages = "io.github.jasonkayzk.consumer.action") @ComponentScan(value = {"io.github.jasonkayzk.consumer.action"}) @PropertySource(value = "classpath:dubbo-consumer.yml", factory = YamlPropertySourceFactory.class) public class YamlConfigConsumerConfig {}
附录 源代码:
参考文章: