spring boot2整合dubbox全注解
前题
dubbox是dubbo的一个升级版,简单说就是本来dubbo是阿里开发的,现在阿里不维护了,当当网拿过去继续开发。本来阿里的dubbo维护到2.6版本,而再高版本的都是当当网维护的就叫成dubbox了。
dubbo的机制是这样的,首先有一个数据中心zookeeper,这里zookeeper的搭建可以参考 zookeeper集群搭建 这篇博客,数据中心的职能只有一个,就是数据的存储。

如图,提供者将自己的服务信息注册到zookeeper中,消费者从zookeeper中取得提供者的服务信息,包括提供者的ip,端口,服务类名参数,这样就可以直接请求提供者所在的服务器,完成调用。
一、dubbox maven导包
1、编译安装
因为dubbox没有编译发布,所以不能够通过maven拉取远程jar包,需要自己编译安装到自己的本地Maven仓库中。从 dubbox github地址 下载项目,在项目根目录下运行
mvn install -Dmaven.test.skip=true 或者在powershell中运行 mvn clean install package '-Dmaven.test.skip=true'
2、项目构建
创建一个maven项目,项目下创建三个module,如图 (这个dubbox是我自己的项目命名,不是官方的dubbox)

这里需要注意,因为是模块项目,所以在dubboapi等module中的pom的parent是dubbox,但是我们的springboot也需要用spring-boot-starter-parent控制版本,所以spring-boot-starter-parent需要定义在dubbox的pom中,继承下去,但是我在dubbox中控制子模块的jar包版本,这会导致一个问题,就是我在dubbox中的版本控制把spring-boot-starter-parent中的版本给冲突掉了。具体情况下面会说。
dubbox的pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>xin.shaozeming</groupId>
<artifactId>dubbox</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>dubboxserver</module>
<module>dubboxclient</module>
<module>dubboxapi</module>
</modules> <properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.BUILD-SNAPSHOT</version>
</parent> <dependencyManagement>
<dependencies>
<!-- dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.8.4</version>
</dependency> <!--zookeeper -->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
<version>0.1</version>
</dependency>
<dependency>
<groupId>net.dubboclub</groupId>
<artifactId>netty4</artifactId>
<version>0.0.6</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
</exclusion>
</exclusions>
</dependency> <!--rest api-->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.7.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.0.7.Final</version>
</dependency> <!-- 如果要使用json序列化 -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>3.0.7.Final</version>
</dependency> <!-- 如果要使用xml序列化 -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>3.0.7.Final</version>
</dependency> <!--kryo序列化-->
<dependency>
<groupId>com.esotericsoftware.kryo</groupId>
<artifactId>kryo</artifactId>
<version>2.24.0</version>
</dependency>
<dependency>
<groupId>de.javakaffee</groupId>
<artifactId>kryo-serializers</artifactId>
<version>0.26</version>
</dependency> <!-- 如果要使用tomcat server -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
<version>8.0.11</version>
</dependency> <!-- 如果要使用netty server -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-netty</artifactId>
<version>3.0.7.Final</version>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
</exclusion>
</exclusions>
</dependency> </dependencies>
</dependencyManagement> <!--<!– Package as an executable jar –>-->
<build>
<finalName>dubbox</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build> <!-- Add Spring repositories -->
<!-- (you don't need this if you are using a .RELEASE version) -->
<repositories>
<repository>
<id>spring-snapshots</id>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<url>https://repo.spring.io/snapshot</url>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories> </project>
dubboxapi的pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbox</artifactId>
<groupId>xin.shaozeming</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbox.api</artifactId> <dependencies> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency> <!--zookeeper -->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
</dependency>
<dependency>
<groupId>net.dubboclub</groupId>
<artifactId>netty4</artifactId>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</dependency> <dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
</dependency> <dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-netty</artifactId>
</dependency> <dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<!--<!– dubbo –>-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
</dependency> <!-- 如果要使用json序列化 -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
</dependency> <!-- 如果要使用xml序列化 -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
</dependency>
<dependency>
<groupId>com.esotericsoftware.kryo</groupId>
<artifactId>kryo</artifactId>
</dependency>
<dependency>
<groupId>de.javakaffee</groupId>
<artifactId>kryo-serializers</artifactId>
</dependency>
</dependencies> </project>
dubboxserver和dubboxclient的pom
<dependencies>
<dependency>
<groupId>xin.shaozeming</groupId>
<artifactId>dubbox.api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
仔细看dubbox和dubboxapi中的jar包,dubboxapi中有 tomcat-embed-core 和 validation-api两个jar包,而dubbox的dependencyManagem中并没有控制版本,这是因为这两个包的版本是spring boot parent里面版本控制继承的tomcat-embed-core springboot2默认的是版本是9,如果这里改成8版本。会出现这样的错
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:155) ~[spring-boot-2.1.0.BUILD-20181030.064057-619.jar:2.1.0.BUILD-SNAPSHOT]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:540) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.1.0.BUILD-20181030.064057-619.jar:2.1.0.BUILD-SNAPSHOT]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) [spring-boot-2.1.0.BUILD-20181030.064057-619.jar:2.1.0.BUILD-SNAPSHOT]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.1.0.BUILD-20181030.064057-619.jar:2.1.0.BUILD-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-2.1.0.BUILD-20181030.064057-619.jar:2.1.0.BUILD-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.0.BUILD-20181030.064057-619.jar:2.1.0.BUILD-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.0.BUILD-20181030.064057-619.jar:2.1.0.BUILD-SNAPSHOT]
at xin.shaozeming.dubboxclient.ClientStart.main(ClientStart.java:17) [classes/:?]
Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getWebServerFactory(ServletWebServerApplicationContext.java:204) ~[spring-boot-2.1.0.BUILD-20181030.064057-619.jar:2.1.0.BUILD-SNAPSHOT]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:178) ~[spring-boot-2.1.0.BUILD-20181030.064057-619.jar:2.1.0.BUILD-SNAPSHOT]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:152) ~[spring-boot-2.1.0.BUILD-20181030.064057-619.jar:2.1.0.BUILD-SNAPSHOT]
... 8 more
这里说这个是希望读者对这个问题注意一下,实际上这里没办法用tomcat,因为如果把这个包改成9版本的,dubbox里面启动tomcat使用的api又有问题了,不过这里服务器可以用netty,这个服务器是消费者和提供者之间通讯的服务器,tomcat和netty的性能没什么差距。所以以上关于tomcat服务器的jar包都可以删掉了,当然不删也没影响。
三、代码实现
provider提供者方面
先看看xml的实现
<dubbo:application name="provider"/>
<dubbo:registry address="zookeeper://47.105.202.148:2181"/>
<dubbo:annotation package="xin.shaozeming.dubboxserver.api" />
<dubbo:protocol name="rest" port="8888" threads="500" contextpath="services" server="netty" accepts="500"/>
<dubbo:service interface="xin.shaozeming.dubboxapi.service.UserService" ref="userService" protocol="rest"/>
javaconfig的实现
/**
* @author: 邵泽铭
* @date: 2018/12/21
* @description:
**/
@Configuration
public class config { private static final String APPLICATION_NAME = "provider"; private static final String REGISTRY_ADDRESS = "zookeeper://47.105.202.148:2181"; private static final String ANNOTATION_PACKAGE = "xin.shaozeming.dubboxserver.api"; @Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName(APPLICATION_NAME);
return applicationConfig;
} @Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress(REGISTRY_ADDRESS);
return registryConfig;
} @Bean
public ProtocolConfig protocolConfig(){
ProtocolConfig protocolConfig=new ProtocolConfig();
protocolConfig.setName("rest");
protocolConfig.setPort(8887);
protocolConfig.setSerialization("kryo");
protocolConfig.setOptimizer(SerializationOptimizerImpl.class.getName());
// protocolConfig.setHost("192.168.0.244");
protocolConfig.setServer("netty");
protocolConfig.setThreads(500);
protocolConfig.setAccepts(500);
protocolConfig.setExtension(
"com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter"
);
return protocolConfig;
} @Bean
public AnnotationBean annotationBean() {
AnnotationBean annotationBean = new AnnotationBean();
annotationBean.setPackage(ANNOTATION_PACKAGE);
return annotationBean;
} }
以下是提供者的接口注解,这里这个service不是spring的service,是dubbox里提供的注解
@Service(interfaceClass = UserService.class)
public class UserServiceProvider implements UserService {
@Override
public User getUser() {
User user=new User();
user.setUserName("szm");
user.setPassword("123456");
return user;
}
}
而rest的注解是需要配置在 UserService 上的,因为 rest的注解不仅仅是提供者接收请求的时候需要,消费者发起请求的时候也需要,之前就是因为这个问题,加上消费者端上没开日志,找了好久的bug。
UserService接口我是定义在dubboxapi里面的
package xin.shaozeming.dubboxapi.service; import com.alibaba.dubbo.rpc.protocol.rest.support.ContentType;
import xin.shaozeming.dubboxapi.po.User; import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType; /**
* \* Created with IntelliJ IDEA.
* \* User: 邵泽铭
* \* Date: 2018/12/21
* \* Time: 9:50
* \* Description:
* \
*/ @Path("user")
public interface UserService { @GET
@Path("getUser")
@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
@Produces({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8})
public User getUser(); }
到这里提供者就配置好了,再看消费者端
xml版本
<dubbo:application name="consumer" />
<dubbo:registry address="zookeeper://47.105.202.148:2181" check="false" />
<!--uncomment this if you want to test dubbo's monitor-->
<!--<dubbo:monitor protocol="registry"/>-->
<dubbo:reference id="userService" interface="xin.shaozeming.dubboxapi.service.UserService" />
javaconfig
@Configuration
public class config {
private static final String APPLICATION_NAME = "consumer"; private static final String REGISTRY_ADDRESS = "zookeeper://47.105.202.148:2181"; private static final String ANNOTATION_PACKAGE = "xin.shaozeming.dubboxclient.controller"; @Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName(APPLICATION_NAME);
return applicationConfig;
} @Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress(REGISTRY_ADDRESS);
return registryConfig;
} @Bean
public AnnotationBean annotationBean() {
AnnotationBean annotationBean = new AnnotationBean();
annotationBean.setPackage(ANNOTATION_PACKAGE);
return annotationBean;
} }
@RestController
public class UserController { @Reference(interfaceClass=UserService.class)
private UserService userService; @GetMapping("/user")
public User getUser(){
return userService.getUser();
} }
到此消费者端就也配置好了
关于duubox的日志,不知道为什么log4j配置了也实现不了,不过后来翻了翻代码,发现可以通过系统属性选择日志实现,start类里面加入以下代码,spring boot整合log4j2可以看这篇文章 sprintboot2整合log4j2
System.setProperty("dubbo.application.logger","slf4j");
还有一个问题,就是对于provider提供者来说,只需要一个netty服务器端口提供服务就可以了,而用springboot启动的时候,springboot会启动一个web,加上netty就是两个服务器,这显然没什么必要,所以可以将spring boot设置成不以web启动方式启动
/**
* @author: 邵泽铭
* @date: 2018/12/21
* @description:
**/ @SpringBootApplication
//@ImportResource("classpath:dubbo-provider.xml")
public class ServerStart {
public static void main(String[] args) throws Exception{ System.setProperty("org.springframework.boot.logging.LoggingSystem","org.springframework.boot.logging.log4j2.Log4J2LoggingSystem");
System.setProperty("dubbo.application.logger","slf4j");
new SpringApplicationBuilder(ServerStart.class)
.web(WebApplicationType.NONE)
.run(args);
} }
一切准备完成之后,启动运行

大功告成!!!
demo项目github地址 https://github.com/1160809039/springboot2-dubbox
spring boot2整合dubbox全注解的更多相关文章
- SSH整合之全注解
SSH整合之全注解 使用注解配置,需要我们额外引入以下jar包
- Spring Boot整合MyBatis(非注解版)
Spring Boot整合MyBatis(非注解版),开发时采用的时IDEA,JDK1.8 直接上图: 文件夹不存在,创建一个新的路径文件夹 创建完成目录结构如下: 本人第一步习惯先把需要的包结构创建 ...
- [Java] Spring boot2 整合 Thymeleaf 后 去除模板缓存
Spring boot2 整合 Thymeleaf 后 去除模板缓存 网上好多文章只是简单粗暴的说,在 application.properties 做如下配置即可: #Thymeleaf cach ...
- MongoDB和Java(5):Spring Data整合MongoDB(注解配置)
最近花了一些时间学习了下MongoDB数据库,感觉还是比较全面系统的,涉及了软件安装.客户端操作.安全认证.副本集和分布式集群搭建,以及使用Spring Data连接MongoDB进行数据操作,收获很 ...
- Spring Boot 整合 Mybatis Annotation 注解的完整 Web 案例
摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 公司需要人.产品.业务和方向,方向又要人.产品.业务和方向,方向… 循环』 本文提纲一. ...
- spring boot2 整合(二)JPA(特别完整!)
JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. JPA 的目标之一是制定一个可以由很多供应商 ...
- spring boot2 整合(一)Mybatis (特别完整!)
大概介绍下流程: 借助idea实现mybatis逆向工程 用xml配置实现整合 用cmd命令行实现mybatis逆向工程 用mapping.xml配置实现数据交互 用注解的方式实现数据交互 首先我的开 ...
- spring boot整合mybatis基于注解开发以及动态sql的使用
让我们回忆一下上篇博客中mybatis是怎样发挥它的作用的,主要是三类文件,第一mapper接口,第二xml文件,第三全局配置文件(application.properties),而今天我们就是来简化 ...
- spring中整合ssm框架注解版
和xml版差不多,只不过创建对象的方式是由spring自动扫描包名,然后命名空间多一行context代码在application.xml中,然后将每个对象通过注解创建和注入: 直接上代码: 1.use ...
随机推荐
- 支持xcode6的缓动函数Easing以及使用示例
支持xcode6的缓动函数Easing以及使用示例 用xcode6新建工程后,直接导致不支持之前的Easing缓动函数的代码,经过修改后就可以正常使用了,虽然比不上POP高大上的动画,但用缓动函数的动 ...
- PHP面试常用算法(推荐)
一.冒泡排序 基本思想: 对需要排序的数组从后往前(逆序)进行多遍的扫描,当发现相邻的两个数值的次序与排序要求的规则不一致时,就将这两个数值进行交换.这样比较小(大)的数值就将逐渐从后面向前面移动. ...
- GO语言 切片的缩短和增长原理
package main import "fmt" //import OS "os" //import "strings" //import ...
- 关于由ajax返回的数据在for循环中只能取到最后一个数的问题
关于由ajax返回的数据在for循环中只能取到最后一个数的问题 以上是来自后台的数据格式.从数据中可以看出,里面包含两个商品,每个商品价格分别为:1.98,13.60.这里我要计算两个商品的总价格,但 ...
- zeromq 笔记
一. 当执行zmq_bind后会进入mute state,直到有进入或者出去的连接发生才会进入ready state 在mute state状态下会根据不同的套接字类型决定是丢弃消息还是阻塞 可参考z ...
- 「bzoj 4180: 字符串计数」
题目 真是一道好题 首先根据一个非常显然的贪心,如果给出了一个串\(S\),我们如何算最小操作次数呢 非常简单,我们直接把\(S\)拉到\(T\)的\(SAM\)上去跑,如果跑不动了就停下来,重新回到 ...
- 【[GDOI2014]拯救莫莉斯】
可能我的状态比较鬼畜,应该没有人这么写 设\(dp[i][j][k]\)表示在第\(i\)行,放置油库的状态为\(j\),实际上周围已经有油库或者本身有油库的状态为\(k\)的时候的最小花费 由于我们 ...
- 5、Spring Cloud-声明式调用 Feign(下)
5.5.在Feign中使用HttpClient和OkhHttp Feign 中.Client 是一个非常重要的组件, Feign 最终发送 Request 请求以及接收 Response响应都是由 C ...
- 9、RabbitMQ-集成Spring
spring封装RabbitMQ看官网:https://spring.io/projects/spring-amqp#learn 开发时根据官网的介绍进行开发,具体的说明都有具体的声明 1.导入依赖 ...
- PHP延迟静态绑定(本文属于转发)
这段时间看项目后台的PHP代码,看到了类似于以下的一段代码,我把它抽出来: <?php class DBHandler { function get() {} } class MySQLHand ...