前言
最近在做一个很复杂的会员综合线下线上商城大型项目,单模块项目无法满足多人开发和架构,很多模块都是重复的就想到了把模块提出来,做成公共模块,基于maven的多模块项目,也好分工开发,也便于后期微服务重构
使用场景
我刚开始创建项目的时候是基于单模块,开发的,我先开发的接口api 项目结构是这样的
core
模块是公共模块,mallapi 是小程序api
,随然单体项目这样的结构也还清晰,但是后面我想到,还有后台web api
,又要重新创建一个项目,core模块,数据库连接mode
l模块这些都是通用的,又是需要在后台项目复制一遍,我觉得很不爽,不友好,代码很冗余,
于是就用SpringBoot+Maven
多模块项目的构建、运行、打包,完美解决问题
项目结构
我创建的基于SpringBoot+Maven
多模块项目结构如下
. ├── kmall-admin │ ├── kmall-admin.iml │ ├── log\ │ │ ├── error │ │ │ ├── error.2021-08-05.log │ │ │ ├── error.2021-08-06.log │ │ │ ├── error.2021-08-09.log │ │ │ └── error.2021-08-10.log │ │ └── info │ │ ├── info.2021-08-05.log │ │ ├── info.2021-08-06.log │ │ ├── info.2021-08-09.log │ │ └── info.2021-08-10.log │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ ├── java │ │ │ │ └── cn │ │ │ │ └── soboys │ │ │ │ └── kmall │ │ │ │ └── admin │ │ │ │ ├── GlobalLogAspect.java │ │ │ │ ├── ServletInitializer.java │ │ │ │ ├── WebApplication.java │ │ │ │ ├── business │ │ │ │ │ └── CouponBusiness.java │ │ │ │ ├── config │ │ │ │ │ └── SwaggerConfigure.java │ │ │ │ ├── controller │ │ │ │ │ └── CouponController.java │ │ │ │ └── swagger │ │ │ │ ├── ApiParamIgnore.java │ │ │ │ ├── SwaggerParamRead.java │ │ │ │ └── SwaggerProperty.java │ │ │ └── resources │ │ │ ├── application-dev.properties │ │ │ ├── application-test.properties │ │ │ ├── application.properties │ │ │ ├── logback-spring.xml │ │ │ └── spy.properties │ │ └── test │ │ └── java │ │ └── UtilsTest.java │ └── target │ └── classes │ ├── application-dev.properties │ ├── application-test.properties │ ├── application.properties │ ├── logback-spring.xml │ └── spy.properties ├── kmall-api │ ├── log\ │ │ ├── error │ │ │ ├── error.2021-08-05.log │ │ │ ├── error.2021-08-06.log │ │ │ ├── error.2021-08-09.log │ │ │ └── error.2021-08-10.log │ │ └── info │ │ ├── info.2021-08-05.log │ │ ├── info.2021-08-06.log │ │ ├── info.2021-08-09.log │ │ └── info.2021-08-10.log │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ ├── java │ │ │ │ └── cn │ │ │ │ └── soboys │ │ │ │ └── kmall │ │ │ │ └── api │ │ │ │ ├── ApiApplication.java │ │ │ │ ├── ApiExceptionHandler.java │ │ │ │ ├── GlobalLogAspect.java │ │ │ │ ├── ServletInitializer.java │ │ │ │ ├── authentication │ │ │ │ │ ├── AuthenticationInterceptor.java │ │ │ │ │ ├── PassToken.java │ │ │ │ │ ├── TokenService.java │ │ │ │ │ └── UserLoginToken.java │ │ │ │ ├── business │ │ │ │ │ └── ActivityBusiness.java │ │ │ │ ├── config │ │ │ │ │ ├── SwaggerConfigure.java │ │ │ │ │ ├── WebMvcCfg.java │ │ │ │ │ ├── WxConfig.java │ │ │ │ │ └── WxProperties.java │ │ │ │ ├── controller │ │ │ │ │ ├── ActivityController.java │ │ │ │ │ ├── BaseController.java │ │ │ │ │ ├── CouponController.java │ │ │ │ │ ├── LoginController.java │ │ │ │ │ ├── PointController.java │ │ │ │ │ ├── PostApiController.java │ │ │ │ │ ├── TestPostApiController.java │ │ │ │ │ └── UserController.java │ │ │ │ └── swagger │ │ │ │ ├── ApiParamIgnore.java │ │ │ │ ├── SwaggerParamRead.java │ │ │ │ └── SwaggerProperty.java │ │ │ └── resources │ │ │ ├── application-dev.properties │ │ │ ├── application-test.properties │ │ │ ├── application.properties │ │ │ ├── logback-spring.xml │ │ │ └── spy.properties │ │ └── test │ │ └── java │ └── target │ └── classes │ ├── application-dev.properties │ ├── application-test.properties │ ├── application.properties │ ├── logback-spring.xml │ └── spy.properties ├── kmall-bean │ ├── kmall-bean.iml │ ├── pom.xml │ └── src │ ├── main │ │ ├── java │ │ │ └── cn │ │ │ └── soboys │ │ │ └── kmall │ │ │ └── bean │ │ │ ├── model │ │ │ │ ├── Coupon.java │ │ │ │ ├── CouponTemplate.java │ │ │ │ ├── PointOrder.java │ │ │ │ ├── PointRecord.java │ │ │ │ ├── User.java │ │ │ │ └── UserCoupon.java │ │ │ ├── params │ │ │ │ ├── LoginParams.java │ │ │ │ ├── SexEnum.java │ │ │ │ └── UserUpdateParams.java │ │ │ └── web │ │ │ └── params │ │ │ └── GenerateCouponParams.java │ │ └── resources │ └── test │ └── java ├── kmall-common │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ ├── java │ │ │ │ └── cn │ │ │ │ └── soboys │ │ │ │ └── kmall │ │ │ │ └── common │ │ │ │ ├── BaseAspectSupport.java │ │ │ │ ├── LogSubject.java │ │ │ │ ├── componnent │ │ │ │ │ ├── CustomIdGenerator.java │ │ │ │ │ └── UniqueNameGenerator.java │ │ │ │ ├── config │ │ │ │ │ ├── MybatisPlusConfigure.java │ │ │ │ │ └── RestTemplateConfig.java │ │ │ │ ├── convert │ │ │ │ │ ├── RequestJson.java │ │ │ │ │ └── RequestJsonHandlerMethodArgumentResolver.java │ │ │ │ ├── exception │ │ │ │ │ ├── AuthenticationException.java │ │ │ │ │ ├── BusinessException.java │ │ │ │ │ ├── GlobalErrorHandler.java │ │ │ │ │ └── GlobalExceptionHandler.java │ │ │ │ ├── ret │ │ │ │ │ ├── ResponseResult.java │ │ │ │ │ ├── ResponseResultHandler.java │ │ │ │ │ ├── ResponseResultInterceptor.java │ │ │ │ │ ├── Result.java │ │ │ │ │ ├── ResultCode.java │ │ │ │ │ └── ResultResponse.java │ │ │ │ ├── serializer │ │ │ │ │ └── json │ │ │ │ │ ├── ClassJsonConfiguration.java │ │ │ │ │ ├── DoubleJsonSerialize.java │ │ │ │ │ ├── MyBeanSerializerModifier.java │ │ │ │ │ ├── NullArrayJsonSerializer.java │ │ │ │ │ ├── NullIntegerJsonSerializer.java │ │ │ │ │ └── NullStringJsonSerializer.java │ │ │ │ ├── utils │ │ │ │ │ ├── HttpClientUtils.java │ │ │ │ │ ├── HttpContextUtil.java │ │ │ │ │ ├── PageRequest.java │ │ │ │ │ ├── QrCodeUtil.java │ │ │ │ │ └── ResponseUtil.java │ │ │ │ └── validator │ │ │ │ ├── IsDateTime.java │ │ │ │ ├── IsDateTimeValidator.java │ │ │ │ ├── IsEnum.java │ │ │ │ ├── IsEnumValidator.java │ │ │ │ ├── IsMobile.java │ │ │ │ ├── IsMobileValidator.java │ │ │ │ ├── IsMoney.java │ │ │ │ ├── IsMoneyValidator.java │ │ │ │ ├── UrlMatcher.java │ │ │ │ └── ValidatorUtil.java │ │ │ └── resources │ │ └── test │ │ └── java │ └── target │ ├── classes │ │ └── cn │ │ └── soboys │ │ └── kmall │ │ └── common │ │ ├── BaseAspectSupport.class │ │ ├── LogSubject.class │ │ ├── componnent │ │ │ └── UniqueNameGenerator.class │ │ ├── config │ │ │ ├── MybatisPlusConfigure.class │ │ │ ├── RestTemplateConfig$1.class │ │ │ └── RestTemplateConfig.class │ │ ├── convert │ │ │ ├── RequestJson.class │ │ │ ├── RequestJsonHandlerMethodArgumentResolver$NamedValueInfo.class │ │ │ ├── RequestJsonHandlerMethodArgumentResolver$RequestCustomParamNamedValueInfo.class │ │ │ ├── RequestJsonHandlerMethodArgumentResolver$RequestPartResolver.class │ │ │ └── RequestJsonHandlerMethodArgumentResolver.class │ │ ├── exception │ │ │ ├── AuthenticationException.class │ │ │ ├── BusinessException.class │ │ │ ├── GlobalErrorHandler.class │ │ │ └── GlobalExceptionHandler.class │ │ ├── ret │ │ │ ├── ResponseResult.class │ │ │ ├── ResponseResultHandler.class │ │ │ ├── ResponseResultInterceptor.class │ │ │ ├── Result.class │ │ │ ├── ResultCode.class │ │ │ └── ResultResponse.class │ │ ├── serializer │ │ │ └── json │ │ │ ├── ClassJsonConfiguration.class │ │ │ ├── DoubleJsonSerialize.class │ │ │ ├── MyBeanSerializerModifier.class │ │ │ ├── NullArrayJsonSerializer.class │ │ │ ├── NullIntegerJsonSerializer.class │ │ │ └── NullStringJsonSerializer.class │ │ ├── utils │ │ │ ├── HttpClientUtils$1.class │ │ │ ├── HttpClientUtils.class │ │ │ ├── HttpContextUtil.class │ │ │ ├── PageRequest.class │ │ │ ├── QrCodeUtil.class │ │ │ └── ResponseUtil.class │ │ └── validator │ │ ├── IsDateTime.class │ │ ├── IsDateTimeValidator.class │ │ ├── IsEnum.class │ │ ├── IsEnumValidator.class │ │ ├── IsMobile.class │ │ ├── IsMobileValidator.class │ │ ├── IsMoney.class │ │ ├── IsMoneyValidator.class │ │ ├── UrlMatcher.class │ │ └── ValidatorUtil.class │ └── generated-sources │ └── annotations ├── kmall-quartz │ ├── kmall-quartz.iml │ ├── pom.xml │ └── src │ ├── main │ │ ├── java │ │ └── resources │ └── test │ └── java ├── kmall-security │ ├── kmall-security.iml │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ ├── java │ │ │ │ └── cn │ │ │ │ └── soboys │ │ │ │ └── kmall │ │ │ │ └── security │ │ │ │ ├── config │ │ │ │ │ ├── JwtAuthenticationEntryPoint.java │ │ │ │ │ ├── JwtRequestFilter.java │ │ │ │ │ └── SecurityConfig.java │ │ │ │ ├── controller │ │ │ │ │ └── LoginController.java │ │ │ │ ├── entity │ │ │ │ │ └── User.java │ │ │ │ ├── mapper │ │ │ │ │ └── UserMapper.java │ │ │ │ ├── service │ │ │ │ │ ├── IUserService.java │ │ │ │ │ ├── JwtUserDetailsService.java │ │ │ │ │ └── impl │ │ │ │ │ └── UserServiceImpl.java │ │ │ │ └── utils │ │ │ │ ├── EncryptPwdUtil.java │ │ │ │ └── JwtTokenUtil.java │ │ │ └── resources │ │ │ └── security.properties │ │ └── test │ │ └── java │ └── target │ ├── classes │ │ ├── cn │ │ │ └── soboys │ │ │ └── kmall │ │ │ └── security │ │ │ ├── config │ │ │ │ ├── JwtAuthenticationEntryPoint.class │ │ │ │ ├── JwtRequestFilter.class │ │ │ │ └── SecurityConfig.class │ │ │ ├── controller │ │ │ │ └── LoginController.class │ │ │ ├── entity │ │ │ │ └── User.class │ │ │ ├── mapper │ │ │ │ └── UserMapper.class │ │ │ ├── service │ │ │ │ ├── IUserService.class │ │ │ │ ├── JwtUserDetailsService.class │ │ │ │ └── impl │ │ │ │ └── UserServiceImpl.class │ │ │ └── utils │ │ │ ├── EncryptPwdUtil.class │ │ │ └── JwtTokenUtil.class │ │ └── security.properties │ └── generated-sources │ └── annotations ├── kmall-service │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ ├── java │ │ │ │ └── cn │ │ │ │ └── soboys │ │ │ │ └── kmall │ │ │ │ ├── MyBatisGeneratorCode.java │ │ │ │ ├── mapper │ │ │ │ │ ├── CouponMapper.java │ │ │ │ │ ├── CouponTemplateMapper.java │ │ │ │ │ ├── PointOrderMapper.java │ │ │ │ │ ├── PointRecordMapper.java │ │ │ │ │ ├── UserCouponMapper.java │ │ │ │ │ └── UserMapper.java │ │ │ │ └── service │ │ │ │ ├── ICouponService.java │ │ │ │ ├── ICouponTemplateService.java │ │ │ │ ├── IPointOrderService.java │ │ │ │ ├── IPointRecordService.java │ │ │ │ ├── IUserCouponService.java │ │ │ │ ├── IUserService.java │ │ │ │ └── impl │ │ │ │ ├── CouponServiceImpl.java │ │ │ │ ├── CouponTemplateServiceImpl.java │ │ │ │ ├── PointOrderServiceImpl.java │ │ │ │ ├── PointRecordServiceImpl.java │ │ │ │ ├── UserCouponServiceImpl.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── resources │ │ │ └── mapper │ │ │ ├── CouponMapper.xml │ │ │ ├── CouponTemplateMapper.xml │ │ │ ├── PointRecordMapper.xml │ │ │ ├── TzUserMapper.xml │ │ │ └── UserCouponMapper.xml │ │ └── test │ │ └── java │ └── target │ └── classes │ └── mapper │ ├── CouponMapper.xml │ ├── CouponTemplateMapper.xml │ ├── PointRecordMapper.xml │ ├── TzUserMapper.xml │ └── UserCouponMapper.xml ├── kmall-sys │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ ├── java │ │ │ │ └── cn │ │ │ │ └── soboys │ │ │ │ └── kmall │ │ │ │ └── sys │ │ │ │ ├── MyBatisGeneratorCode.java │ │ │ │ ├── controller │ │ │ │ │ ├── MenuController.java │ │ │ │ │ ├── TRoleController.java │ │ │ │ │ ├── TRoleMenuController.java │ │ │ │ │ ├── TUserRoleController.java │ │ │ │ │ └── UserController.java │ │ │ │ ├── entity │ │ │ │ │ ├── Menu.java │ │ │ │ │ ├── Role.java │ │ │ │ │ ├── RoleMenu.java │ │ │ │ │ ├── User.java │ │ │ │ │ └── UserRole.java │ │ │ │ ├── mapper │ │ │ │ │ ├── MenuMapper.java │ │ │ │ │ ├── RoleMapper.java │ │ │ │ │ ├── RoleMenuMapper.java │ │ │ │ │ ├── UserMapper.java │ │ │ │ │ └── UserRoleMapper.java │ │ │ │ ├── params │ │ │ │ ├── result │ │ │ │ │ └── MenuResult.java │ │ │ │ └── service │ │ │ │ ├── IMenuService.java │ │ │ │ ├── IRoleMenuService.java │ │ │ │ ├── IRoleService.java │ │ │ │ ├── IUserRoleService.java │ │ │ │ ├── IUserService.java │ │ │ │ └── impl │ │ │ │ ├── MenuServiceImpl.java │ │ │ │ ├── RoleMenuServiceImpl.java │ │ │ │ ├── RoleServiceImpl.java │ │ │ │ ├── UserRoleServiceImpl.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── resources │ │ │ └── mapper │ │ │ └── MenuMapper.xml │ │ └── test │ │ └── java │ └── target │ ├── classes │ │ ├── cn │ │ │ └── soboys │ │ │ └── kmall │ │ │ └── sys │ │ │ ├── MyBatisGeneratorCode$1.class │ │ │ ├── MyBatisGeneratorCode$2.class │ │ │ ├── MyBatisGeneratorCode.class │ │ │ ├── controller │ │ │ │ ├── TRoleController.class │ │ │ │ ├── TRoleMenuController.class │ │ │ │ └── TUserRoleController.class │ │ │ ├── entity │ │ │ │ ├── Menu.class │ │ │ │ ├── Role.class │ │ │ │ ├── RoleMenu.class │ │ │ │ ├── User.class │ │ │ │ └── UserRole.class │ │ │ ├── mapper │ │ │ │ ├── MenuMapper.class │ │ │ │ ├── RoleMapper.class │ │ │ │ ├── RoleMenuMapper.class │ │ │ │ ├── UserMapper.class │ │ │ │ └── UserRoleMapper.class │ │ │ └── result │ │ │ └── MenuResult.class │ │ └── mapper │ │ └── MenuMapper.xml │ └── generated-sources │ └── annotations ├── kmall.iml ├── pom.xml └── src ├── main │ ├── java │ └── resources │ └── mapper │ ├── PointOrderMapper.xml │ ├── TMenuMapper.xml │ ├── TRoleMapper.xml │ ├── TRoleMenuMapper.xml │ ├── TUserMapper.xml │ └── TUserRoleMapper.xml └── test └── java
-
kmall-admin
模块 后台模块,后台接口api -
kmall-api
模块前端小程序,app的api -
kmall-bean
实体bean 模块 -
kmall-common
公共模块 -
kmall-quartz
定时任务模块 -
kmall-service
服务模块 -
kmall-security
安全认证模块 -
kmall-sys
后台系统模块
项目依赖管理打包
首先最外层kmall
是父模块 管理着所有的版本和依赖,外层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>cn.soboys.kmall</groupId> <artifactId>kmall</artifactId> <version>1.0-SNAPSHOT</version> <modules> <module>kmall-common</module> <module>kmall-bean</module> <module>kmall-service</module> <module>kmall-api</module> <module>kmall-admin</module> <module>kmall-sys</module> <module>kmall-security</module> <module>kmall-quartz</module> </modules> <packaging>pom</packaging> <!--引用springBoot父项目--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.7</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <kmall.version>1.0-SNAPSHOT</kmall.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> <maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version> <maven.resources.plugin.version>3.2.0</maven.resources.plugin.version> <maven.jar.plugin.version>3.2.0</maven.jar.plugin.version> <maven-war-plugin.version>3.2.3</maven-war-plugin.version> <spring-boot.version>2.4.7</spring-boot.version> <mybatis.plus.boot.starter.version>3.4.3</mybatis.plus.boot.starter.version> <mybatis-plus-generator.version>3.4.1</mybatis-plus-generator.version> <freemarker.version>2.3.31</freemarker.version> <p6spy.version>3.9.0</p6spy.version> <fastjson.version>1.2.76</fastjson.version> <jjwt.version>0.9.1</jjwt.version> <java-jwt.version>3.15.0</java-jwt.version> <weixin-java-miniapp.version>4.0.0</weixin-java-miniapp.version> <weixin-java-pay.version>4.0.0</weixin-java-pay.version> <hutool.version>5.7.0</hutool.version> <ip2region.version>1.0.3.RELEASE</ip2region.version> <knife4j.version>3.0.1</knife4j.version> </properties> <!--dependencyManagement里只是声明依赖,并不自动实现引入,因此子项目需要显示的声明需要用的依赖 如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项, 并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本 --> <!--统一管理依赖的版本号--> <dependencyManagement> <dependencies> <dependency> <groupId>cn.soboys.kmall</groupId> <artifactId>kmall-common</artifactId> <version>${kmall.version}</version> </dependency> <dependency> <groupId>cn.soboys.kmall</groupId> <artifactId>kmall-bean</artifactId> <version>${kmall.version}</version> </dependency> <dependency> <groupId>cn.soboys.kmall</groupId> <artifactId>kmall-service</artifactId> <version>${kmall.version}</version> </dependency> <dependency> <groupId>cn.soboys.kmall</groupId> <artifactId>kmall-security</artifactId> <version>${kmall.version}</version> </dependency> <dependency> <groupId>cn.soboys.kmall</groupId> <artifactId>kmall-sys</artifactId> <version>${kmall.version}</version> </dependency> <!--<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.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis.plus.boot.starter.version}</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>${mybatis-plus-generator.version}</version> </dependency> <dependency> <groupId>com.github.hiwepy</groupId> <artifactId>ip2region-spring-boot-starter</artifactId> <version>${ip2region.version}</version> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>${knife4j.version}</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>${freemarker.version}</version> </dependency> <dependency> <groupId>p6spy</groupId> <artifactId>p6spy</artifactId> <version>${p6spy.version}</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>${jjwt.version}</version> </dependency> <dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-miniapp</artifactId> <version>${weixin-java-miniapp.version}</version> </dependency> <dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-pay</artifactId> <version>${weixin-java-pay.version}</version> </dependency> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>${java-jwt.version}</version> </dependency> <!-- <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>${hutool.version}</version> </dependency>--> <!--json 序列化--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-core</artifactId> <version>${hutool.version}</version> <!--<exclusions> <exclusion> <groupId>cn.hutool</groupId> <artifactId>hutool-setting</artifactId> </exclusion> </exclusions>--> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-json</artifactId> <version>${hutool.version}</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-http</artifactId> <version>${hutool.version}</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-extra</artifactId> <version>${hutool.version}</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-crypto</artifactId> <version>${hutool.version}</version> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> </dependencies> <!-- 环境信息 --> <profiles> <!-- 标机开发环境 --> <profile> <id>dev</id> <properties> <activeProfile>dev</activeProfile> <serviceactive>servicedev</serviceactive> <businessactive>businessdev</businessactive> </properties> <activation> <activeByDefault>false</activeByDefault> </activation> </profile> <!-- 测试环境 --> <profile> <id>test</id> <properties> <activeProfile>test</activeProfile> <serviceactive>servicetest</serviceactive> <businessactive>businesstest</businessactive> </properties> <activation> <activeByDefault>true</activeByDefault> </activation> </profile> <!-- 生产环境 --> <profile> <id>product</id> <properties> <activeProfile>product</activeProfile> <serviceactive>serviceproduct</serviceactive> <businessactive>businessproduct</businessactive> </properties> <activation> <activeByDefault>false</activeByDefault> </activation> </profile> </profiles> </project>
我们可以把很多公用
的配置放在父模块中如打包环境配置
,jar包版本依赖
,那样的话子模块的pom.xml配置的东西就非常的少了,方便阅读。
这里父项目的pom.xml主要是配置了都需要的SpringBoot
的相关引用,这样的话我们子项目完全不需要再重复引用了。另外其配置了profiles
属性,这个属性是让我们区分多环境是打包哪些配置文件,其id参数
就是我们的要打包环境的一个标识,比如我们打包测试环境我们只需要执行clean install -Ptest即可,-P后面的值即为这个id值,其中properties属性里面的列表是标识该环境生效的配置文件,属性里面的是SpringBoot配置文件后面的值,比如application-serviceproduct.properties其值就为serviceproduct
我们在看下kmall-common
公共模块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>kmall</artifactId> <groupId>cn.soboys.kmall</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>kmall-common</artifactId> <dependencies> <!--aop 切面--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!--ip获取位置--> <dependency> <groupId>com.github.hiwepy</groupId> <artifactId>ip2region-spring-boot-starter</artifactId> </dependency> <!--api 文档--> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> </dependency> <!--数据库jar################--> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!--mybatPlus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> </dependency> <!--生成器依赖--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> </dependency> <!--MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖:--> <!--添加 模板引擎 依赖,MyBatis-Plus 支持 Velocity(默认)、 Freemarker、Beetl,用户可以选择自己熟悉的模板引擎, 如果都不满足您的要求,可以采用自定义模板引擎。--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> </dependency> <!-- p6spy sql拦截调试--> <dependency> <groupId>p6spy</groupId> <artifactId>p6spy</artifactId> </dependency> <!--数据库jar################--> <!--微信小程序工具sdk--> <dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-miniapp</artifactId> </dependency> <!--微信支付工具sdk--> <dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-pay</artifactId> </dependency> <!--hutool 工具库--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-core</artifactId> <!--<exclusions> <exclusion> <groupId>cn.hutool</groupId> <artifactId>hutool-setting</artifactId> </exclusion> </exclusions>--> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-json</artifactId> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-http</artifactId> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-extra</artifactId> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-crypto</artifactId> </dependency> <!--json 序列化--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency> </dependencies> </project>
这里因为kmall
父模块做了项目版本管理,所以这里只需要引入依赖就可以,依赖版本由父模块决定
然后我们在看一下kmall-bean
模块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>kmall</artifactId> <groupId>cn.soboys.kmall</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>kmall-bean</artifactId> <dependencies> <dependency> <groupId>cn.soboys.kmall</groupId> <artifactId>kmall-common</artifactId> </dependency> <!--参数校验--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> </dependencies> </project>
依赖于公共模块,也单独引用了参数校验依赖
我们在看一下kmall-service
模块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>kmall</artifactId> <groupId>cn.soboys.kmall</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>kmall-service</artifactId> <dependencies> <dependency> <groupId>cn.soboys.kmall</groupId> <artifactId>kmall-common</artifactId> </dependency> <dependency> <groupId>cn.soboys.kmall</groupId> <artifactId>kmall-bean</artifactId> </dependency> </dependencies> </project>
依赖于公共模块,和bean模块
接下来我们看下两个主模块 kmall-api
有springboot启动类入口
ApiApplication
是springboot启动类
package cn.soboys.kmall.api; import cn.hutool.extra.spring.EnableSpringUtil; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; @SpringBootApplication(scanBasePackages = {"cn.soboys.kmall"}) @MapperScan("cn.soboys.kmall.mapper") @EnableSpringUtil public class ApiApplication { private static ApplicationContext applicationContext; public static void main(String[] args) { applicationContext = SpringApplication.run(ApiApplication.class, args); //displayAllBeans(); } /** * 打印所以装载的bean */ public static void displayAllBeans() { String[] allBeanNames = applicationContext.getBeanDefinitionNames(); for (String beanName : allBeanNames) { System.out.println(beanName); } } }
我们来看一下他的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>kmall</artifactId> <groupId>cn.soboys.kmall</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>kmall-api</artifactId> <packaging>war</packaging> <dependencies> <dependency> <groupId>cn.soboys.kmall</groupId> <artifactId>kmall-service</artifactId> </dependency> <!--jwt 认证--> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> </dependency> </dependencies> <!--打包--> <build> <resources> <resource> <filtering>true</filtering> <directory>src/main/resources</directory> </resource> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven.compiler.plugin.version}</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>${maven.resources.plugin.version}</version> <configuration> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>${maven.jar.plugin.version}</version> </plugin> <!-- <plugin> <artifactId>maven-war-plugin</artifactId> <version>${maven-war-plugin.version}</version> <configuration> <!– Exclude JCL and LOG4J since all logging should go through SLF4J. Note that we're excluding log4j-<version>.jar but keeping log4j-over-slf4j-<version>.jar –> <packagingExcludes> WEB-INF/lib/hutool-setting.jar, </packagingExcludes> </configuration> </plugin>--> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中--> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
这里pom做了一个打包的处理,我们需要打包时候只需要通过 IDEA 进行打包就可以啦
package进行打包war 发布到服务器就可以运行啦
我们再来看一下后台模块kmall-admin
有springboot启动类入口WebApplication
@SpringBootApplication @MapperScan(value = {"cn.soboys.kmall.mapper","cn.soboys.kmall.sys.mapper","cn.soboys.kmall.security.mapper"},nameGenerator = UniqueNameGenerator.class) @ComponentScan(value = {"cn.soboys.kmall"},nameGenerator = UniqueNameGenerator.class) public class WebApplication { private static ApplicationContext applicationContext; public static void main(String[] args) { applicationContext = SpringApplication.run(WebApplication.class, args); //displayAllBeans(); } /** * 打印所以装载的bean */ public static void displayAllBeans() { String[] allBeanNames = applicationContext.getBeanDefinitionNames(); for (String beanName : allBeanNames) { System.out.println(beanName); } } }
看下它的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>kmall</artifactId> <groupId>cn.soboys.kmall</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <packaging>war</packaging> <artifactId>kmall-admin</artifactId> <dependencies> <dependency> <groupId>cn.soboys.kmall</groupId> <artifactId>kmall-service</artifactId> </dependency> <dependency> <groupId>cn.soboys.kmall</groupId> <artifactId>kmall-sys</artifactId> </dependency> </dependencies> <!--打包--> <build> <resources> <resource> <filtering>true</filtering> <directory>src/main/resources</directory> </resource> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven.compiler.plugin.version}</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>${maven.resources.plugin.version}</version> <configuration> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>${maven.jar.plugin.version}</version> </plugin> <!-- <plugin> <artifactId>maven-war-plugin</artifactId> <version>${maven-war-plugin.version}</version> <configuration> <!– Exclude JCL and LOG4J since all logging should go through SLF4J. Note that we're excluding log4j-<version>.jar but keeping log4j-over-slf4j-<version>.jar –> <packagingExcludes> WEB-INF/lib/hutool-setting.jar, </packagingExcludes> </configuration> </plugin>--> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中--> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
这里我配置文件中环境激活是根据父模块pom中配置走的spring.profiles.active=@activeProfile@,@serviceactive@,@businessactive@
这里的值取值与父pom中环境打包配置
然后我们在打包前勾选需要打包的环境就可以了
这样基于SpringBoot+Maven 多模块项目的构建、运行、打包实战就完成啦,如果有什么疑问可以关注我公众猿小叔