0:序言
最近在学习廖师兄的 Spring Cloud 微服务实战,贴上慕课网的课程链接:Spring Cloud 微服务实战。在学习完5.8章节,完成了基本的订单入库功能。此时的项目此时仍存在以下几个问题
1:应用间通信的 listProductForOrder()方法返回的是 ProductInfo 类对象集合,但是这个类是直接对应数据库的,直接暴露给其他服务不好。
2:在order服务中,也定义了CartDTO类和ProductInfo类,类重复定义,效率低
3:在order服务中调用product服务时,需要知道具体的url,在实际操作中不太现实
因此,5.9章节将项目改造成多模块,课程未讲改造细节,现将具体改造步骤贴出(文中有些地方没贴出详细代码,请见最后的项目源码 )
1:Product(父工程)项目配置
修改 product 项目的 pom.xml
<packaging>jar</packaging> 修改成 ,使当前项目成为父工程
<packaging>pom</packaging>
Product项目共划分为三个子模块,分别是product-common,product-server,product-client。 common的职责为公用的对象(CartDTO、ProductInfo),server负责全部业务逻辑,client负责对外通用接口(ProductClient);其中server依赖于common,client依赖于common。server和client之间没有依赖关系。
<!-- 模块说明:这里声明多个子模块 -->
<modules>
<module>common</module>
<module>server</module>
<module>client</module>
</modules>
2:子模块配置 common server client
1:创建子模块
因为我用的是Eclpise,所以在创建子工程时只能采用 Spring Initizlizr 。分别创建common,server,client三个项目,创建时的依赖不用填。下载好依次解压到 product的根目录下。解压后的图如下(注意三个子模块所在文件夹的名称要与 上图 module的对应,不然可能发生child module ---not exist 问题):
2:配置 pom.xml,指定依赖关系
client的pom.xml:
<?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>product</artifactId>
<groupId>com.imooc</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<!--子工程名称 -->
<artifactId>product-client</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<!-- 指定需要依赖的子工程 -->
<dependency>
<groupId>com.imooc</groupId>
<artifactId>product-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
common的pom.xml :
<?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>product</artifactId>
<groupId>com.imooc</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>product-common</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
server的pom.xml:注意,我的mysql版本为 8.0.11,需改成自己的版本。
<?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>product</artifactId>
<groupId>com.imooc</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>product-server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- 指定子工程 product-common的依赖 -->
<dependency>
<groupId>com.imooc</groupId>
<artifactId>product-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
</project>
完成上面步骤后,Eclpise中导入项目,项目结构如下图。
3:改造子模块代码
1:common模块
在序言中提到,公用对象包括CartDTO和ProductInfo,因此,在common中新建下面两个类分别对应于CartDTO 和 ProductInfo。内容大致一样,详细见最后项目源码。
2:server模块
server模块的功能是处理全部的业务逻辑,所以需要将product src包下的所有内容都复制到 server模块下,是所有内容,包括java,resourse,test等。然后再启动在server 中的ProductApplication主启动类,正常运行则代表复制完成。
完成上面步骤后,删除product目录下的 src包。
此时,在server模块的,仍使用的是CartDTO,返回给其他服务的仍是ProductInfo对象。很明显,需要修改成common中的DecreaseStockInput 和 ProductInfoOutPut。service层和serviceImpl 一样需要改。改造完成后项目结构图如下.
运行test下的 ProductServiceTest,验证改造是否成功。
3:client模块
为方便其他服务调用product,在product中写上自己的FeginClient类,类内容见后面项目源码。
4:运维部署(多模块项目打包)
1:添加打包插件
注意:多模块项目仅仅需要在启动类所在的模块添加打包插件即可!!不要在父类添加打包插件,因为那样会导致全部子模块都使用spring-boot-maven-plugin的方式来打包,而server模块引common 的jar 需要的是裸露的类文件
本案例的启动模块是 server , 只需在它的pom.xml 添加打包插件(spring-boot-maven-plugin),父类的这个插件记得删除:
<!--多模块打包:只需在启动类所在模块的POM文件:指定打包插件 -->
<build>
<plugins>
<plugin>
<!--该插件主要用途:构建可执行的JAR -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2:打包工程
Eclpise中步骤:
1:父类工程右键---run as --maven clean ,然后 父类工程右键---run as --maven install
3:启动项目
通过命令行启动server下的项目:
server\target>java -jar product-server-0.0.1-SNAPSHOT.jar
改造完成!
Github源码:Srping Boot 项目多模块化改造