赞
踩
随着项目的不断发展,需求和业务的不断细化与添加,工程代码会越来越庞大,包结构也越来越复杂,不同方面的代码之间相互耦合,杂乱而无章,并且开发人员也都同时在这一个项目里修改,合并代码时必然会出现各种各样的问题,而且当一位新的人员参与进项目,很难对项目有一个直观的感受,这间接的导致了开发效率的下降。
多模块化,正式解决上述问题而产生的,总的来说模块化开发有以下几点好处:
本文以springboot集成nacos的注册中心和feign为例,编译器用的Intellij IDEA,Java版本是1.8。
其实我用模块化开发,主要原因是微服务之间用feign互相调用接口的时候,发现实体类的参数没法传递啊,传个map感觉又不太雅观不正规,所以就想到了这个办法,把公用的实体类放到pom里面,直接搞成模块化
File—>New—>Project
最外层的父模块,无须启动类,直接创建maven工程
自定义创建好了,直接Next,Next,Finish完事!
下面看一下父模块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"> <!--声明项目描述符遵循哪一个POM模型版本。模型本身的版本很少改变,虽然如此,但它仍然是必不可少的,这是为了当Maven引入了新的特性或者其他模型变更的时候,确保稳定性。 --> <modelVersion>4.0.0</modelVersion> <!--父项目的坐标。如果项目中没有规定某个元素的值,那么父项目中的对应值即为项目的默认值。 坐标包括group ID,artifact ID和 version。 --> <!--父模块为springboot--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> </parent> <!-- 公司或者组织的唯一标志,并且配置时生成的路径也是由此生成, 如com.companyname.project-group,maven会将该项目打成的jar包放本地路径:/com/companyname/project-group --> <!--项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。并且构建时生成的路径也是由此生成, 如com.mycompany.app生成的相对路径为:/com/mycompany/app --> <groupId>com.shopping.nacos</groupId> <!-- 项目的唯一ID,一个groupId下面可能多个项目,就是靠artifactId来区分的 --> <!-- 构件的标识符,它和group ID一起唯一标识一个构件。换句话说,你不能有两个不同的项目拥有同样的artifact ID和groupID;在某个 特定的group ID下,artifact ID也必须是唯一的。构件是项目产生的或使用的一个东西,Maven为项目产生的构件包括:JARs,源 码,二进制发布和WARs等。 --> <artifactId>shopping</artifactId> <!-- 版本号 --> <version>1.0-SNAPSHOT</version> <!--打包方式,项目产生的构件类型,例如jar、war、ear、pom。插件可以创建他们自己的构件类型,所以前面列的不是全部构件类型 --> <packaging>pom</packaging> <!--统一管理版本号--> <properties> <java.version>1.8</java.version> <spingboot.version>2.3.1.RELEASE</spingboot.version> <cloud.version>Greenwich.SR2</cloud.version> <cloud.alibaba.version>0.2.2.RELEASE</cloud.alibaba.version> <mybatis-plus.version>3.1.0</mybatis-plus.version> </properties> <!--引入的下一层级的所有子模块--> <modules> </modules> <!--<dependencyManagement>主要管理版本,对于子类继承同一个父类是很有用的,集中管理依赖版本不添加依赖关系,对于其中定义的版本,子pom不一定要继承父pom所定义的版本。--> <!--指定cloud的版本和nacos的版本--> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${cloud.alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!--引入的依赖,这里引入了,子模块就默认继承了父模块的依赖--> <dependencies> <!--公用依赖:springboot web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--公用依赖:springboot test--> <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> <!--<!–lombok–>--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!--StringUtils工具包--> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> </dependencies> <!--这里是打包时候的设置,如果有入口类,还需要加一个入口类的设置.还有其他问题什么的,自行百度吧--> <build> <plugins> <!--这是因为测试代码时遇到错误,它会停止编译。只需要在pom.xml的<project>里添加以下配置,使得测试出错不影响项目的编译。--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <testFailureIgnore>true</testFailureIgnore> </configuration> </plugin> </plugins> </build> </project>
pom可以分为几块去看
公用子模块,顾名思义,就是都能用到的功能,抽离出来,然后谁用,就在Pom里引入就行了。
比如下面这个例子中,mybatis的分页插件,我单独抽出来了,其实好像并没有什么必要,一是因为举例说明,二是如果以后又什么新功能配置加入,好做横向扩展,到时候就看出作用。
公用的pojo我也抽离出来了,这的作用主要是一些微服务之间共享的实体类
下面我们从父模块下面创建公用的子模块
公用子模块就是用来放公用的接口,方法,配置,还有实体类等等
因为这个模块是公用的模块,比如放一些基本配置啊,pojo实体类啊什么的,所以这里不用启动类,直接创建个maven工程就可以了,基本流程还是和上面一样,选择Module,选择Maven,创建就完事
这是创建好的公用子模块,里面还要放各种公用的模块,依然把src删了。
配置一下这个公用子模块的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>shopping</artifactId> <groupId>com.shopping.nacos</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <!--项目的唯一ID,就是刚才创建时候的名字--> <artifactId>shopping-common</artifactId> <!--因为这里下面还有子模块,这里的打包方式也要用pom--> <packaging>pom</packaging> <description>公用模块</description> <!--下面的子模块--> <modules> </modules> </project>
然后再以相同的步骤,在这个子模块里,再创建子模块,依然是创建maven工程。这个嵌套的子模块,就是具体的公用功能了
不同的是src目录别删,因为要写具体的功能
在java文件夹下,创建目录
首先把java文件夹变成蓝色文件夹,Sources类型,这样才能在下面创建java class
创建目录结构,之所以这样创建,是因为整个项目总体需要统一起来,当引入其他模块的时候,其他模块的启动类才可以把这里的启动配置加载进去
创建好了Mybatisplus的分页插件
下面贴出mybatis子模块的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>shopping-common</artifactId> <groupId>com.cloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>shopping-common-mybatis</artifactId> <!--这里具体到功能了,需要打成jar包了--> <packaging>jar</packaging> <description>mybatis公用类</description> <dependencies> <!--=========mybatis plus======================--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus.version}</version> </dependency> <!--<!–<!–=========mysql======================–>–>--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies> </project>
注意,这里的packaging要设置成jar了,因为具体到功能模块了
公用子模块的创建就到这了,其他需要啥公用的功能,往里加就完事了
下面再创建一个pojo公用实体类的模块
前面创建步骤和上面一样
这里需要引入刚才创建的mybatisplus模块,因为实体类需要mybatisplus的@TableName等注解
还有什么其他的公用的模块,比如日志,权限,工具类等等公用的模块都可以像上述模块一样往里加,下面将功能模块的创建,以及如何调用这些公用的模块
功能模块就是具体到业务里的某个功能了,作为微服务,是需要有启动类的,所以需要创建springboot项目,并且打包方式为jar
首先我们创建一个模块,暂且就定义为订单服务吧
创建流程
首先要做的是
注意,是删掉这个文件夹,把启动类,复制到nacos文件夹下。因为所有模块的启动类,这里尽量都要保证在com.shopping.nacos下,因为这样启动的时候才会正确加载启动所有要引入的配置项。往后的模块也需要这样做,都统一起来
下面我们来修改一下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> <groupId>com.shopping.nacos</groupId> <artifactId>shopping</artifactId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.shopping.nacos</groupId> <artifactId>shopping-order</artifactId> <version>0.0.1-SNAPSHOT</version> <name>shopping-order</name> <packaging>jar</packaging> <description>订单信息微服务</description> <dependencies> <!--引入自定义mybatis插件模块--> <dependency> <groupId>com.shopping.nacos</groupId> <artifactId>shopping-common-mybatis</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--引入alibaba nacos注册中心依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.shopping.nacos</groupId> <artifactId>shopping-common-pojo</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- Redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!--Redisson--> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.8.2</version> </dependency> </dependencies> <build> <plugins> <!--这里引入了spring-boot-maven-plugin,打包时会去扫描项目main方法入口,也就是说引入该配置,你就必须在项目src/main/java/下创建一个spring-boot启动类:--> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
修改了parent为自己的父类,packaging打包方式为jar,还有把指定版本的properties删掉,因为这些都要写在父依赖的pom里。下面dependencies里面需要引入本模块需要的依赖。
注意这里引入了上面自己的Mybatis和Pojo,这样确实方便和舒适很多。
然后,找到最外层父依赖的pom,把这个模块加进去
很清楚了吧兄弟
下面,来配置订单服务模块的配置文件
server: port: 8001 spring: application: #服务名,微服务用此名字注册服务并发现服务 name: shopping-order cloud: nacos: discovery: #nacos服务注册与发现地址 server-addr: IP:8848 #数据源配置 datasource: username: root password: 密码 url: jdbc:mysql://IP:3306/shopping_mall?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC driver-class-name: com.mysql.jdbc.Driver #Redis配置 redis: database: 0 host: IP port: 6379 password: 密码 timeout: 1000 mybatis-plus: # 如果是放在src/main/java目录下 classpath:/com/yourpackage/*/mapper/*Mapper.xml mapper-locations: classpath:mybatis/*Mapper.xml typeAliasesPackage: com.shoppingmall.wares.pojo global-config: db-config: #id-type: uuid #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断" field-strategy: 1 #驼峰下划线转换 #db-column-underline: true #刷新mapper 调试神器 #refresh-mapper: true #数据库大写下划线转换 #capital-mode: true # Sequence序列接口实现类配置 #key-generator: com.baomidou.mybatisplus.incrementer.OracleKeyGenerator #逻辑删除配置(下面3个配置) #logic-delete-value: 1 #logic-not-delete-value: 0 #sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector #自定义填充策略接口实现 #meta-object-handler: com.baomidou.springboot.MyMetaObjectHandler configuration: #配置返回数据库(column下划线命名&&返回java实体是驼峰命名),自动匹配无需as(没开启这个,SQL需要写as: select user_id as userId) #true:开启数据库下划线对应实体类转驼峰;false:不开启 map-underscore-to-camel-case: true cache-enabled: false #配置JdbcTypeForNull, oracle数据库必须配置 jdbc-type-for-null: 'null' log-impl: org.apache.ibatis.logging.stdout.StdOutImpl database-id: mysql
注意name: shopping-order这个服务名字很重要,服务之间通信全靠他了。
下面,启动类加入@EnableDiscoveryClient,开启Naocs服务与发现注册中心
然后创建个controller,写个post请求的接口
启动订单模块,看nacos控制台,服务列表,已经有shopping-order这个服务了
下面我们创建一个消费服务的库存模块
和上面的步骤一样,我就不重复贴了。这里测试一下,库存模块来消费订单模块的接口,所以加入了feign。
<!--引入alibaba nacos--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--feign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>com.shopping.nacos</groupId> <artifactId>shopping-common-mybatis</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.shopping.nacos</groupId> <artifactId>shopping-common-pojo</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
这是需要引入的依赖
启动类上加入2个注解,一个是nacos注册中心服务发现的注解@EnableDiscoveryClient,另一个是feign的注解@EnableFeignClients
配置文件,贴代码
server: port: 8002 spring: application: name: shopping-order cloud: nacos: discovery: server-addr: IP:8848 datasource: username: root password: zaqxsw url: jdbc:mysql://IP:3306/shopping_mall?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC driver-class-name: com.mysql.jdbc.Driver mybatis-plus: mapper-locations: classpath:mybatis/*Mapper.xml typeAliasesPackage: com.shoppingmall.wares.pojo global-config: db-config: field-strategy: 1 configuration: map-underscore-to-camel-case: true cache-enabled: false jdbc-type-for-null: 'null' log-impl: org.apache.ibatis.logging.stdout.StdOutImpl database-id: mysql #fengin请求超时时间,单位毫秒 ribbon: ReadTimeout: 5000 ConnectTimeout: 5000
@FeignClient(“shopping-order”)注解,表明了这是个feign类,括号里是调用的服务名字,下面的写的接口,是调用"shopping-order"服务暴露的接口方法,对照上面的订单服务
然后在controller层去调用这个接口,去测试一下,feign的接口是不需要实现的
controller层
启动库存服务,看一下nacos操作平台,库存服务也注册到服务发现的列表里去了
然后用postman测试一下,库存服务的端口是8002
好了,feign消费微服务成功!
下面我们将这这2个服务打包,放到不同的服务器上
订单服务放在201服务器上,库存服务放在202服务器上
OK,完事。
如果服务之间的feign接口,有实体类参数的话,直接pom里引入公用的pojo实体类,这么干,也可以搞定了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。