注:本实例是在dubbo-admin和zookeeper,已安装好的前提下操作的,关于两个的安装可以查看我前面的博客。
https://www.cnblogs.com/personblog/p/14537931.html
https://www.cnblogs.com/personblog/p/13391810.html
RPC的内容:远程过程调用,简单实现对User根据ID进行查询服务。
- 创建一个Maven空项目,作为项目的父工程,此工程的子项目基于Spring Boot 2.3.7 实现
在父模块下,需要创建的子模块
<!-- 模块说明:这里声明多个子模块 --> <modules> <module>dubblo-interface</module> <module>user-service-provider</module> <module>order-service-consumer</module> </modules>
完整父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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- 基本信息 --> <modelVersion>4.0.0</modelVersion> <name>dubblo</name> <packaging>pom</packaging> <description>Demo project for Spring Boot</description> <!-- 项目说明:这里作为聚合工程的父工程 --> <groupId>com.howdy</groupId> <artifactId>dubblo</artifactId> <version>1.0-SNAPSHOT</version> <!-- 模块说明:这里声明多个子模块 --> <modules> <module>dubblo-interface</module> <module>user-service-provider</module> <module>order-service-consumer</module> </modules> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- 版本说明:这里统一管理依赖的版本号 --> <dependency> <groupId>com.howdy</groupId> <artifactId>dubblo-interface</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>com.howdy</groupId> <artifactId>user-service-provider</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>com.howdy</groupId> <artifactId>order-service-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.3.7.RELEASE</version> <configuration> <mainClass>com.howdy.dubblo.DubbloApplication</mainClass> <classifier>exec</classifier> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
创建好的时目录结构如下,父级项目中的src文件及子文件用不到,可以删除掉
- 创建子模块,比如创建dubblo-interface子模块,在dubblo上右键--New--Module
其它默认,直接下一步即可
-
创建公共API
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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>dubblo</artifactId> <groupId>com.howdy</groupId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.howdy</groupId> <artifactId>dubblo-interface</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <!-- SLf4j 日志记录--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> <version>1.18.12</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.54</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> </dependency> </dependencies> </project>
相关代码如下:
package com.howdy.dubblo.bean; import lombok.Data; import org.springframework.stereotype.Component; import java.util.Date; //通过这个注解,可以不用写gettersetter方法 @Data @Component public class UserBean { private int id; private String uname; private int uage; private Date create_time; }
package com.howdy.dubblo.service; import com.howdy.dubblo.bean.UserBean; import org.springframework.stereotype.Repository; import java.util.List; @Repository public interface Order_Service { List<UserBean> InitOrder(int userId); }
package com.howdy.dubblo.service; import com.howdy.dubblo.bean.UserBean; import org.springframework.stereotype.Repository; import java.util.List; @Repository public interface User_infoService { List<UserBean> getUserList(int userId); }
-
服务提供者,目录结构和相关代码如下
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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.howdy</groupId> <artifactId>user-service-provider</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>com.howdy</groupId> <artifactId>dubblo</artifactId> <version>1.0-SNAPSHOT</version> </parent> <properties> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> </properties> <dependencies> <!-- 引入公共API,以实现其接口 --> <dependency> <groupId>com.howdy</groupId> <artifactId>dubblo-interface</artifactId> </dependency> <!-- 引入spring-boot-starter以及dubbo和curator的依赖 --> <dependency> <groupId>com.alibaba.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>0.2.0</version> </dependency> <!-- Spring Boot相关依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>${spring-boot.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>${spring-boot.version}</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <!--该插件主要用途:构建可执行的JAR --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
dubbo提供了@Service注解,可将类声明为提供方,省去了大量配置的麻烦
package com.howdy.userserviceprovider.service.impl; import com.alibaba.dubbo.config.annotation.Service; import com.howdy.dubblo.bean.UserBean; import com.howdy.dubblo.service.User_infoService; import org.springframework.stereotype.Component; import java.util.*; @Service //属于Dubbo的@Service注解,非Spring 作用:暴露服务 @Component public class UserServiceImpl implements User_infoService { @Override public List<UserBean> getUserList(int userId) { List<UserBean> list=new ArrayList<UserBean>(); UserBean userBean=new UserBean(); userBean.setId(1); userBean.setUname("张三"); userBean.setUage(20); userBean.setCreate_time(new Date()); list.add(userBean); return list; } }
通过属性配置的方式设置application.properties
#当前服务/应用的名字 dubbo.application.name=user-service-provider #注册中心的协议和地址 dubbo.registry.protocol=zookeeper dubbo.registry.address=127.0.0.1:2181 #通信规则(通信协议和接口) dubbo.protocol.name=dubbo dubbo.protocol.port=20880 #连接监控中心 dubbo.monitor.protocol=registry #开启包扫描,可替代 @EnableDubbo 注解 ##dubbo.scan.base-packages=com.howdy.dubblo
springboot容器根据配置启动服务提供方,这里需要添加 @EnableDubbo 注解
package com.howdy.userserviceprovider; import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; // 开启基于注解的dubbo功能(主要是包扫描@DubboComponentScan) // 也可以在配置文件中使用dubbo.scan.base-package来替代 @EnableDubbo @EnableDubbo @SpringBootApplication public class UserServiceProviderApplication { public static void main(String[] args) { SpringApplication.run(UserServiceProviderApplication.class, args); } }
服务方启动成功,如图:
-
服务消费者
消费者工程在初始化时设置为web项目,结构如下
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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>dubblo</artifactId> <groupId>com.howdy</groupId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.howdy</groupId> <artifactId>order-service-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <!-- 引入公共API,以实现其接口 --> <dependency> <groupId>com.howdy</groupId> <artifactId>dubblo-interface</artifactId> </dependency> <!-- 引入spring-boot-starter以及dubbo和curator的依赖 --> <dependency> <groupId>com.alibaba.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>0.2.0</version> </dependency> <!-- Spring Boot相关依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- springboot web模块 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <!--该插件主要用途:构建可执行的JAR --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
dubbo提供了@Reference注解,可替换@Autowired注解,用于引入远程服务
package com.howdy.orderserviceconsumer.service.impl; import com.alibaba.dubbo.config.annotation.Reference; import com.howdy.dubblo.bean.UserBean; import com.howdy.dubblo.service.Order_Service; import com.howdy.dubblo.service.User_infoService; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Date; import java.util.List; @Service //属于spring注解,引入springframework.stereotype.Service 包 @Component public class OrderServiceImpl implements Order_Service { @Reference(version = "*", check = true) User_infoService user_infoService; @Override public List<UserBean> InitOrder(int userId) { List<UserBean> list=new ArrayList<UserBean>(); UserBean userBean=new UserBean(); userBean.setId(2); userBean.setUname("李四"); userBean.setUage(30); userBean.setCreate_time(new Date()); list.add(userBean); return list; } }
package com.howdy.orderserviceconsumer.controller; import com.howdy.dubblo.bean.UserBean; import com.howdy.dubblo.service.Order_Service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController //以json格式返回 @RequestMapping("/api") public class OrderController { @Autowired Order_Service orderService; @GetMapping("/initOrder") public List<UserBean> initOrder(@RequestParam("uid") int userId){ return orderService.InitOrder(1); } }
配置文件application.properties
#避免和监控中心端口冲突,设为8081端口访问 server.port=8081 #当前服务/应用的名字 dubbo.application.name=order-service-consumer dubbo.registry.address=zookeeper://127.0.0.1:2181 dubbo.monitor.protocol=registry
启动类同样加上@EnableDubbo注解
package com.howdy.orderserviceconsumer; import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @EnableDubbo @SpringBootApplication public class OrderServiceConsumerApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceConsumerApplication.class, args); } }
启动消费方,测试调用,成功如下: