前言
最近在做一个很复杂的会员综合线下线上商城大型项目,单模块项目无法满足多人开发和架构,很多模块都是重复的就想到了把模块提出来,做成公共模块,基于maven的多模块项目,也好分工开发,也便于后期微服务重构
使用场景
我刚开始创建项目的时候是基于单模块,开发的,我先开发的接口api 项目结构是这样的

core模块是公共模块,mallapi 是小程序api,随然单体项目这样的结构也还清晰,但是后面我想到,还有后台web api,又要重新创建一个项目,core模块,数据库连接model模块这些都是通用的,又是需要在后台项目复制一遍,我觉得很不爽,不友好,代码很冗余,
于是就用SpringBoot+Maven 多模块项目的构建、运行、打包,完美解决问题
项目结构
我创建的基于SpringBoot+Maven多模块项目结构如下

1. 2├── kmall-admin 3│ ├── kmall-admin.iml 4│ ├── log\ 5│ │ ├── error 6│ │ │ ├── error.2021-08-05.log 7│ │ │ ├── error.2021-08-06.log 8│ │ │ ├── error.2021-08-09.log 9│ │ │ └── error.2021-08-10.log 10│ │ └── info 11│ │ ├── info.2021-08-05.log 12│ │ ├── info.2021-08-06.log 13│ │ ├── info.2021-08-09.log 14│ │ └── info.2021-08-10.log 15│ ├── pom.xml 16│ ├── src 17│ │ ├── main 18│ │ │ ├── java 19│ │ │ │ └── cn 20│ │ │ │ └── soboys 21│ │ │ │ └── kmall 22│ │ │ │ └── admin 23│ │ │ │ ├── GlobalLogAspect.java 24│ │ │ │ ├── ServletInitializer.java 25│ │ │ │ ├── WebApplication.java 26│ │ │ │ ├── business 27│ │ │ │ │ └── CouponBusiness.java 28│ │ │ │ ├── config 29│ │ │ │ │ └── SwaggerConfigure.java 30│ │ │ │ ├── controller 31│ │ │ │ │ └── CouponController.java 32│ │ │ │ └── swagger 33│ │ │ │ ├── ApiParamIgnore.java 34│ │ │ │ ├── SwaggerParamRead.java 35│ │ │ │ └── SwaggerProperty.java 36│ │ │ └── resources 37│ │ │ ├── application-dev.properties 38│ │ │ ├── application-test.properties 39│ │ │ ├── application.properties 40│ │ │ ├── logback-spring.xml 41│ │ │ └── spy.properties 42│ │ └── test 43│ │ └── java 44│ │ └── UtilsTest.java 45│ └── target 46│ └── classes 47│ ├── application-dev.properties 48│ ├── application-test.properties 49│ ├── application.properties 50│ ├── logback-spring.xml 51│ └── spy.properties 52├── kmall-api 53│ ├── log\ 54│ │ ├── error 55│ │ │ ├── error.2021-08-05.log 56│ │ │ ├── error.2021-08-06.log 57│ │ │ ├── error.2021-08-09.log 58│ │ │ └── error.2021-08-10.log 59│ │ └── info 60│ │ ├── info.2021-08-05.log 61│ │ ├── info.2021-08-06.log 62│ │ ├── info.2021-08-09.log 63│ │ └── info.2021-08-10.log 64│ ├── pom.xml 65│ ├── src 66│ │ ├── main 67│ │ │ ├── java 68│ │ │ │ └── cn 69│ │ │ │ └── soboys 70│ │ │ │ └── kmall 71│ │ │ │ └── api 72│ │ │ │ ├── ApiApplication.java 73│ │ │ │ ├── ApiExceptionHandler.java 74│ │ │ │ ├── GlobalLogAspect.java 75│ │ │ │ ├── ServletInitializer.java 76│ │ │ │ ├── authentication 77│ │ │ │ │ ├── AuthenticationInterceptor.java 78│ │ │ │ │ ├── PassToken.java 79│ │ │ │ │ ├── TokenService.java 80│ │ │ │ │ └── UserLoginToken.java 81│ │ │ │ ├── business 82│ │ │ │ │ └── ActivityBusiness.java 83│ │ │ │ ├── config 84│ │ │ │ │ ├── SwaggerConfigure.java 85│ │ │ │ │ ├── WebMvcCfg.java 86│ │ │ │ │ ├── WxConfig.java 87│ │ │ │ │ └── WxProperties.java 88│ │ │ │ ├── controller 89│ │ │ │ │ ├── ActivityController.java 90│ │ │ │ │ ├── BaseController.java 91│ │ │ │ │ ├── CouponController.java 92│ │ │ │ │ ├── LoginController.java 93│ │ │ │ │ ├── PointController.java 94│ │ │ │ │ ├── PostApiController.java 95│ │ │ │ │ ├── TestPostApiController.java 96│ │ │ │ │ └── UserController.java 97│ │ │ │ └── swagger 98│ │ │ │ ├── ApiParamIgnore.java 99│ │ │ │ ├── SwaggerParamRead.java 100│ │ │ │ └── SwaggerProperty.java 101│ │ │ └── resources 102│ │ │ ├── application-dev.properties 103│ │ │ ├── application-test.properties 104│ │ │ ├── application.properties 105│ │ │ ├── logback-spring.xml 106│ │ │ └── spy.properties 107│ │ └── test 108│ │ └── java 109│ └── target 110│ └── classes 111│ ├── application-dev.properties 112│ ├── application-test.properties 113│ ├── application.properties 114│ ├── logback-spring.xml 115│ └── spy.properties 116├── kmall-bean 117│ ├── kmall-bean.iml 118│ ├── pom.xml 119│ └── src 120│ ├── main 121│ │ ├── java 122│ │ │ └── cn 123│ │ │ └── soboys 124│ │ │ └── kmall 125│ │ │ └── bean 126│ │ │ ├── model 127│ │ │ │ ├── Coupon.java 128│ │ │ │ ├── CouponTemplate.java 129│ │ │ │ ├── PointOrder.java 130│ │ │ │ ├── PointRecord.java 131│ │ │ │ ├── User.java 132│ │ │ │ └── UserCoupon.java 133│ │ │ ├── params 134│ │ │ │ ├── LoginParams.java 135│ │ │ │ ├── SexEnum.java 136│ │ │ │ └── UserUpdateParams.java 137│ │ │ └── web 138│ │ │ └── params 139│ │ │ └── GenerateCouponParams.java 140│ │ └── resources 141│ └── test 142│ └── java 143├── kmall-common 144│ ├── pom.xml 145│ ├── src 146│ │ ├── main 147│ │ │ ├── java 148│ │ │ │ └── cn 149│ │ │ │ └── soboys 150│ │ │ │ └── kmall 151│ │ │ │ └── common 152│ │ │ │ ├── BaseAspectSupport.java 153│ │ │ │ ├── LogSubject.java 154│ │ │ │ ├── componnent 155│ │ │ │ │ ├── CustomIdGenerator.java 156│ │ │ │ │ └── UniqueNameGenerator.java 157│ │ │ │ ├── config 158│ │ │ │ │ ├── MybatisPlusConfigure.java 159│ │ │ │ │ └── RestTemplateConfig.java 160│ │ │ │ ├── convert 161│ │ │ │ │ ├── RequestJson.java 162│ │ │ │ │ └── RequestJsonHandlerMethodArgumentResolver.java 163│ │ │ │ ├── exception 164│ │ │ │ │ ├── AuthenticationException.java 165│ │ │ │ │ ├── BusinessException.java 166│ │ │ │ │ ├── GlobalErrorHandler.java 167│ │ │ │ │ └── GlobalExceptionHandler.java 168│ │ │ │ ├── ret 169│ │ │ │ │ ├── ResponseResult.java 170│ │ │ │ │ ├── ResponseResultHandler.java 171│ │ │ │ │ ├── ResponseResultInterceptor.java 172│ │ │ │ │ ├── Result.java 173│ │ │ │ │ ├── ResultCode.java 174│ │ │ │ │ └── ResultResponse.java 175│ │ │ │ ├── serializer 176│ │ │ │ │ └── json 177│ │ │ │ │ ├── ClassJsonConfiguration.java 178│ │ │ │ │ ├── DoubleJsonSerialize.java 179│ │ │ │ │ ├── MyBeanSerializerModifier.java 180│ │ │ │ │ ├── NullArrayJsonSerializer.java 181│ │ │ │ │ ├── NullIntegerJsonSerializer.java 182│ │ │ │ │ └── NullStringJsonSerializer.java 183│ │ │ │ ├── utils 184│ │ │ │ │ ├── HttpClientUtils.java 185│ │ │ │ │ ├── HttpContextUtil.java 186│ │ │ │ │ ├── PageRequest.java 187│ │ │ │ │ ├── QrCodeUtil.java 188│ │ │ │ │ └── ResponseUtil.java 189│ │ │ │ └── validator 190│ │ │ │ ├── IsDateTime.java 191│ │ │ │ ├── IsDateTimeValidator.java 192│ │ │ │ ├── IsEnum.java 193│ │ │ │ ├── IsEnumValidator.java 194│ │ │ │ ├── IsMobile.java 195│ │ │ │ ├── IsMobileValidator.java 196│ │ │ │ ├── IsMoney.java 197│ │ │ │ ├── IsMoneyValidator.java 198│ │ │ │ ├── UrlMatcher.java 199│ │ │ │ └── ValidatorUtil.java 200│ │ │ └── resources 201│ │ └── test 202│ │ └── java 203│ └── target 204│ ├── classes 205│ │ └── cn 206│ │ └── soboys 207│ │ └── kmall 208│ │ └── common 209│ │ ├── BaseAspectSupport.class 210│ │ ├── LogSubject.class 211│ │ ├── componnent 212│ │ │ └── UniqueNameGenerator.class 213│ │ ├── config 214│ │ │ ├── MybatisPlusConfigure.class 215│ │ │ ├── RestTemplateConfig$1.class 216│ │ │ └── RestTemplateConfig.class 217│ │ ├── convert 218│ │ │ ├── RequestJson.class 219│ │ │ ├── RequestJsonHandlerMethodArgumentResolver$NamedValueInfo.class 220│ │ │ ├── RequestJsonHandlerMethodArgumentResolver$RequestCustomParamNamedValueInfo.class 221│ │ │ ├── RequestJsonHandlerMethodArgumentResolver$RequestPartResolver.class 222│ │ │ └── RequestJsonHandlerMethodArgumentResolver.class 223│ │ ├── exception 224│ │ │ ├── AuthenticationException.class 225│ │ │ ├── BusinessException.class 226│ │ │ ├── GlobalErrorHandler.class 227│ │ │ └── GlobalExceptionHandler.class 228│ │ ├── ret 229│ │ │ ├── ResponseResult.class 230│ │ │ ├── ResponseResultHandler.class 231│ │ │ ├── ResponseResultInterceptor.class 232│ │ │ ├── Result.class 233│ │ │ ├── ResultCode.class 234│ │ │ └── ResultResponse.class 235│ │ ├── serializer 236│ │ │ └── json 237│ │ │ ├── ClassJsonConfiguration.class 238│ │ │ ├── DoubleJsonSerialize.class 239│ │ │ ├── MyBeanSerializerModifier.class 240│ │ │ ├── NullArrayJsonSerializer.class 241│ │ │ ├── NullIntegerJsonSerializer.class 242│ │ │ └── NullStringJsonSerializer.class 243│ │ ├── utils 244│ │ │ ├── HttpClientUtils$1.class 245│ │ │ ├── HttpClientUtils.class 246│ │ │ ├── HttpContextUtil.class 247│ │ │ ├── PageRequest.class 248│ │ │ ├── QrCodeUtil.class 249│ │ │ └── ResponseUtil.class 250│ │ └── validator 251│ │ ├── IsDateTime.class 252│ │ ├── IsDateTimeValidator.class 253│ │ ├── IsEnum.class 254│ │ ├── IsEnumValidator.class 255│ │ ├── IsMobile.class 256│ │ ├── IsMobileValidator.class 257│ │ ├── IsMoney.class 258│ │ ├── IsMoneyValidator.class 259│ │ ├── UrlMatcher.class 260│ │ └── ValidatorUtil.class 261│ └── generated-sources 262│ └── annotations 263├── kmall-quartz 264│ ├── kmall-quartz.iml 265│ ├── pom.xml 266│ └── src 267│ ├── main 268│ │ ├── java 269│ │ └── resources 270│ └── test 271│ └── java 272├── kmall-security 273│ ├── kmall-security.iml 274│ ├── pom.xml 275│ ├── src 276│ │ ├── main 277│ │ │ ├── java 278│ │ │ │ └── cn 279│ │ │ │ └── soboys 280│ │ │ │ └── kmall 281│ │ │ │ └── security 282│ │ │ │ ├── config 283│ │ │ │ │ ├── JwtAuthenticationEntryPoint.java 284│ │ │ │ │ ├── JwtRequestFilter.java 285│ │ │ │ │ └── SecurityConfig.java 286│ │ │ │ ├── controller 287│ │ │ │ │ └── LoginController.java 288│ │ │ │ ├── entity 289│ │ │ │ │ └── User.java 290│ │ │ │ ├── mapper 291│ │ │ │ │ └── UserMapper.java 292│ │ │ │ ├── service 293│ │ │ │ │ ├── IUserService.java 294│ │ │ │ │ ├── JwtUserDetailsService.java 295│ │ │ │ │ └── impl 296│ │ │ │ │ └── UserServiceImpl.java 297│ │ │ │ └── utils 298│ │ │ │ ├── EncryptPwdUtil.java 299│ │ │ │ └── JwtTokenUtil.java 300│ │ │ └── resources 301│ │ │ └── security.properties 302│ │ └── test 303│ │ └── java 304│ └── target 305│ ├── classes 306│ │ ├── cn 307│ │ │ └── soboys 308│ │ │ └── kmall 309│ │ │ └── security 310│ │ │ ├── config 311│ │ │ │ ├── JwtAuthenticationEntryPoint.class 312│ │ │ │ ├── JwtRequestFilter.class 313│ │ │ │ └── SecurityConfig.class 314│ │ │ ├── controller 315│ │ │ │ └── LoginController.class 316│ │ │ ├── entity 317│ │ │ │ └── User.class 318│ │ │ ├── mapper 319│ │ │ │ └── UserMapper.class 320│ │ │ ├── service 321│ │ │ │ ├── IUserService.class 322│ │ │ │ ├── JwtUserDetailsService.class 323│ │ │ │ └── impl 324│ │ │ │ └── UserServiceImpl.class 325│ │ │ └── utils 326│ │ │ ├── EncryptPwdUtil.class 327│ │ │ └── JwtTokenUtil.class 328│ │ └── security.properties 329│ └── generated-sources 330│ └── annotations 331├── kmall-service 332│ ├── pom.xml 333│ ├── src 334│ │ ├── main 335│ │ │ ├── java 336│ │ │ │ └── cn 337│ │ │ │ └── soboys 338│ │ │ │ └── kmall 339│ │ │ │ ├── MyBatisGeneratorCode.java 340│ │ │ │ ├── mapper 341│ │ │ │ │ ├── CouponMapper.java 342│ │ │ │ │ ├── CouponTemplateMapper.java 343│ │ │ │ │ ├── PointOrderMapper.java 344│ │ │ │ │ ├── PointRecordMapper.java 345│ │ │ │ │ ├── UserCouponMapper.java 346│ │ │ │ │ └── UserMapper.java 347│ │ │ │ └── service 348│ │ │ │ ├── ICouponService.java 349│ │ │ │ ├── ICouponTemplateService.java 350│ │ │ │ ├── IPointOrderService.java 351│ │ │ │ ├── IPointRecordService.java 352│ │ │ │ ├── IUserCouponService.java 353│ │ │ │ ├── IUserService.java 354│ │ │ │ └── impl 355│ │ │ │ ├── CouponServiceImpl.java 356│ │ │ │ ├── CouponTemplateServiceImpl.java 357│ │ │ │ ├── PointOrderServiceImpl.java 358│ │ │ │ ├── PointRecordServiceImpl.java 359│ │ │ │ ├── UserCouponServiceImpl.java 360│ │ │ │ └── UserServiceImpl.java 361│ │ │ └── resources 362│ │ │ └── mapper 363│ │ │ ├── CouponMapper.xml 364│ │ │ ├── CouponTemplateMapper.xml 365│ │ │ ├── PointRecordMapper.xml 366│ │ │ ├── TzUserMapper.xml 367│ │ │ └── UserCouponMapper.xml 368│ │ └── test 369│ │ └── java 370│ └── target 371│ └── classes 372│ └── mapper 373│ ├── CouponMapper.xml 374│ ├── CouponTemplateMapper.xml 375│ ├── PointRecordMapper.xml 376│ ├── TzUserMapper.xml 377│ └── UserCouponMapper.xml 378├── kmall-sys 379│ ├── pom.xml 380│ ├── src 381│ │ ├── main 382│ │ │ ├── java 383│ │ │ │ └── cn 384│ │ │ │ └── soboys 385│ │ │ │ └── kmall 386│ │ │ │ └── sys 387│ │ │ │ ├── MyBatisGeneratorCode.java 388│ │ │ │ ├── controller 389│ │ │ │ │ ├── MenuController.java 390│ │ │ │ │ ├── TRoleController.java 391│ │ │ │ │ ├── TRoleMenuController.java 392│ │ │ │ │ ├── TUserRoleController.java 393│ │ │ │ │ └── UserController.java 394│ │ │ │ ├── entity 395│ │ │ │ │ ├── Menu.java 396│ │ │ │ │ ├── Role.java 397│ │ │ │ │ ├── RoleMenu.java 398│ │ │ │ │ ├── User.java 399│ │ │ │ │ └── UserRole.java 400│ │ │ │ ├── mapper 401│ │ │ │ │ ├── MenuMapper.java 402│ │ │ │ │ ├── RoleMapper.java 403│ │ │ │ │ ├── RoleMenuMapper.java 404│ │ │ │ │ ├── UserMapper.java 405│ │ │ │ │ └── UserRoleMapper.java 406│ │ │ │ ├── params 407│ │ │ │ ├── result 408│ │ │ │ │ └── MenuResult.java 409│ │ │ │ └── service 410│ │ │ │ ├── IMenuService.java 411│ │ │ │ ├── IRoleMenuService.java 412│ │ │ │ ├── IRoleService.java 413│ │ │ │ ├── IUserRoleService.java 414│ │ │ │ ├── IUserService.java 415│ │ │ │ └── impl 416│ │ │ │ ├── MenuServiceImpl.java 417│ │ │ │ ├── RoleMenuServiceImpl.java 418│ │ │ │ ├── RoleServiceImpl.java 419│ │ │ │ ├── UserRoleServiceImpl.java 420│ │ │ │ └── UserServiceImpl.java 421│ │ │ └── resources 422│ │ │ └── mapper 423│ │ │ └── MenuMapper.xml 424│ │ └── test 425│ │ └── java 426│ └── target 427│ ├── classes 428│ │ ├── cn 429│ │ │ └── soboys 430│ │ │ └── kmall 431│ │ │ └── sys 432│ │ │ ├── MyBatisGeneratorCode$1.class 433│ │ │ ├── MyBatisGeneratorCode$2.class 434│ │ │ ├── MyBatisGeneratorCode.class 435│ │ │ ├── controller 436│ │ │ │ ├── TRoleController.class 437│ │ │ │ ├── TRoleMenuController.class 438│ │ │ │ └── TUserRoleController.class 439│ │ │ ├── entity 440│ │ │ │ ├── Menu.class 441│ │ │ │ ├── Role.class 442│ │ │ │ ├── RoleMenu.class 443│ │ │ │ ├── User.class 444│ │ │ │ └── UserRole.class 445│ │ │ ├── mapper 446│ │ │ │ ├── MenuMapper.class 447│ │ │ │ ├── RoleMapper.class 448│ │ │ │ ├── RoleMenuMapper.class 449│ │ │ │ ├── UserMapper.class 450│ │ │ │ └── UserRoleMapper.class 451│ │ │ └── result 452│ │ │ └── MenuResult.class 453│ │ └── mapper 454│ │ └── MenuMapper.xml 455│ └── generated-sources 456│ └── annotations 457├── kmall.iml 458├── pom.xml 459└── src 460 ├── main 461 │ ├── java 462 │ └── resources 463 │ └── mapper 464 │ ├── PointOrderMapper.xml 465 │ ├── TMenuMapper.xml 466 │ ├── TRoleMapper.xml 467 │ ├── TRoleMenuMapper.xml 468 │ ├── TUserMapper.xml 469 │ └── TUserRoleMapper.xml 470 └── test 471 └── java 472 473
kmall-admin模块 后台模块,后台接口apikmall-api模块前端小程序,app的apikmall-bean实体bean 模块kmall-common公共模块kmall-quartz定时任务模块kmall-service服务模块kmall-security安全认证模块kmall-sys后台系统模块
项目依赖管理打包
首先最外层kmall是父模块 管理着所有的版本和依赖,外层pom如下
1<?xml version="1.0" encoding="UTF-8"?> 2<project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>cn.soboys.kmall</groupId> 8 <artifactId>kmall</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 11 <modules> 12 <module>kmall-common</module> 13 <module>kmall-bean</module> 14 <module>kmall-service</module> 15 <module>kmall-api</module> 16 <module>kmall-admin</module> 17 <module>kmall-sys</module> 18 <module>kmall-security</module> 19 <module>kmall-quartz</module> 20 </modules> 21 <packaging>pom</packaging> 22 23 <!--引用springBoot父项目--> 24 <parent> 25 <groupId>org.springframework.boot</groupId> 26 <artifactId>spring-boot-starter-parent</artifactId> 27 <version>2.4.7</version> 28 <relativePath/> <!-- lookup parent from repository --> 29 </parent> 30 31 <properties> 32 <kmall.version>1.0-SNAPSHOT</kmall.version> 33 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 34 <java.version>1.8</java.version> 35 <maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version> 36 <maven.resources.plugin.version>3.2.0</maven.resources.plugin.version> 37 <maven.jar.plugin.version>3.2.0</maven.jar.plugin.version> 38 <maven-war-plugin.version>3.2.3</maven-war-plugin.version> 39 <spring-boot.version>2.4.7</spring-boot.version> 40 <mybatis.plus.boot.starter.version>3.4.3</mybatis.plus.boot.starter.version> 41 <mybatis-plus-generator.version>3.4.1</mybatis-plus-generator.version> 42 <freemarker.version>2.3.31</freemarker.version> 43 <p6spy.version>3.9.0</p6spy.version> 44 <fastjson.version>1.2.76</fastjson.version> 45 <jjwt.version>0.9.1</jjwt.version> 46 <java-jwt.version>3.15.0</java-jwt.version> 47 <weixin-java-miniapp.version>4.0.0</weixin-java-miniapp.version> 48 <weixin-java-pay.version>4.0.0</weixin-java-pay.version> 49 <hutool.version>5.7.0</hutool.version> 50 <ip2region.version>1.0.3.RELEASE</ip2region.version> 51 <knife4j.version>3.0.1</knife4j.version> 52 </properties> 53 54 <!--dependencyManagement里只是声明依赖,并不自动实现引入,因此子项目需要显示的声明需要用的依赖 55 56 如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项, 57 并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本 58 --> 59 <!--统一管理依赖的版本号--> 60 <dependencyManagement> 61 <dependencies> 62 <dependency> 63 <groupId>cn.soboys.kmall</groupId> 64 <artifactId>kmall-common</artifactId> 65 <version>${kmall.version}</version> 66 </dependency> 67 <dependency> 68 <groupId>cn.soboys.kmall</groupId> 69 <artifactId>kmall-bean</artifactId> 70 <version>${kmall.version}</version> 71 </dependency> 72 <dependency> 73 <groupId>cn.soboys.kmall</groupId> 74 <artifactId>kmall-service</artifactId> 75 <version>${kmall.version}</version> 76 </dependency> 77 <dependency> 78 <groupId>cn.soboys.kmall</groupId> 79 <artifactId>kmall-security</artifactId> 80 <version>${kmall.version}</version> 81 </dependency> 82 <dependency> 83 <groupId>cn.soboys.kmall</groupId> 84 <artifactId>kmall-sys</artifactId> 85 <version>${kmall.version}</version> 86 </dependency> 87 <!--<dependency> 88 <groupId>org.springframework.boot</groupId> 89 <artifactId>spring-boot-dependencies</artifactId> 90 <version>${spring-boot.version}</version> 91 <type>pom</type> 92 <scope>import</scope> 93 </dependency>--> 94 <dependency> 95 <groupId>com.baomidou</groupId> 96 <artifactId>mybatis-plus-boot-starter</artifactId> 97 <version>${mybatis.plus.boot.starter.version}</version> 98 </dependency> 99 <dependency> 100 <groupId>com.baomidou</groupId> 101 <artifactId>mybatis-plus-generator</artifactId> 102 <version>${mybatis-plus-generator.version}</version> 103 </dependency> 104 <dependency> 105 <groupId>com.github.hiwepy</groupId> 106 <artifactId>ip2region-spring-boot-starter</artifactId> 107 <version>${ip2region.version}</version> 108 </dependency> 109 <dependency> 110 <groupId>com.github.xiaoymin</groupId> 111 <artifactId>knife4j-spring-boot-starter</artifactId> 112 <version>${knife4j.version}</version> 113 </dependency> 114 <dependency> 115 <groupId>org.freemarker</groupId> 116 <artifactId>freemarker</artifactId> 117 <version>${freemarker.version}</version> 118 </dependency> 119 <dependency> 120 <groupId>p6spy</groupId> 121 <artifactId>p6spy</artifactId> 122 <version>${p6spy.version}</version> 123 </dependency> 124 <dependency> 125 <groupId>io.jsonwebtoken</groupId> 126 <artifactId>jjwt</artifactId> 127 <version>${jjwt.version}</version> 128 </dependency> 129 <dependency> 130 <groupId>com.github.binarywang</groupId> 131 <artifactId>weixin-java-miniapp</artifactId> 132 <version>${weixin-java-miniapp.version}</version> 133 </dependency> 134 <dependency> 135 <groupId>com.github.binarywang</groupId> 136 <artifactId>weixin-java-pay</artifactId> 137 <version>${weixin-java-pay.version}</version> 138 </dependency> 139 <dependency> 140 <groupId>com.auth0</groupId> 141 <artifactId>java-jwt</artifactId> 142 <version>${java-jwt.version}</version> 143 </dependency> 144 <!-- <dependency> 145 <groupId>cn.hutool</groupId> 146 <artifactId>hutool-all</artifactId> 147 <version>${hutool.version}</version> 148 </dependency>--> 149 <!--json 序列化--> 150 <dependency> 151 <groupId>com.alibaba</groupId> 152 <artifactId>fastjson</artifactId> 153 <version>${fastjson.version}</version> 154 </dependency> 155 156 <dependency> 157 <groupId>cn.hutool</groupId> 158 <artifactId>hutool-core</artifactId> 159 <version>${hutool.version}</version> 160 <!--<exclusions> 161 <exclusion> 162 <groupId>cn.hutool</groupId> 163 <artifactId>hutool-setting</artifactId> 164 </exclusion> 165 </exclusions>--> 166 </dependency> 167 <dependency> 168 <groupId>cn.hutool</groupId> 169 <artifactId>hutool-json</artifactId> 170 <version>${hutool.version}</version> 171 </dependency> 172 <dependency> 173 <groupId>cn.hutool</groupId> 174 <artifactId>hutool-http</artifactId> 175 <version>${hutool.version}</version> 176 </dependency> 177 <dependency> 178 <groupId>cn.hutool</groupId> 179 <artifactId>hutool-extra</artifactId> 180 <version>${hutool.version}</version> 181 </dependency> 182 <dependency> 183 <groupId>cn.hutool</groupId> 184 <artifactId>hutool-crypto</artifactId> 185 <version>${hutool.version}</version> 186 </dependency> 187 </dependencies> 188 </dependencyManagement> 189 190 <dependencies> 191 <dependency> 192 <groupId>org.projectlombok</groupId> 193 <artifactId>lombok</artifactId> 194 <scope>provided</scope> 195 </dependency> 196 <dependency> 197 <groupId>org.springframework.boot</groupId> 198 <artifactId>spring-boot-configuration-processor</artifactId> 199 <optional>true</optional> 200 </dependency> 201 <dependency> 202 <groupId>org.springframework.boot</groupId> 203 <artifactId>spring-boot-starter-web</artifactId> 204 </dependency> 205 <dependency> 206 <groupId>org.springframework.boot</groupId> 207 <artifactId>spring-boot-starter-tomcat</artifactId> 208 <scope>provided</scope> 209 </dependency> 210 </dependencies> 211 212 <!-- 环境信息 --> 213 <profiles> 214 <!-- 标机开发环境 --> 215 <profile> 216 <id>dev</id> 217 <properties> 218 <activeProfile>dev</activeProfile> 219 <serviceactive>servicedev</serviceactive> 220 <businessactive>businessdev</businessactive> 221 </properties> 222 <activation> 223 <activeByDefault>false</activeByDefault> 224 </activation> 225 </profile> 226 <!-- 测试环境 --> 227 <profile> 228 <id>test</id> 229 <properties> 230 <activeProfile>test</activeProfile> 231 <serviceactive>servicetest</serviceactive> 232 <businessactive>businesstest</businessactive> 233 </properties> 234 <activation> 235 <activeByDefault>true</activeByDefault> 236 </activation> 237 </profile> 238 <!-- 生产环境 --> 239 <profile> 240 <id>product</id> 241 <properties> 242 <activeProfile>product</activeProfile> 243 <serviceactive>serviceproduct</serviceactive> 244 <businessactive>businessproduct</businessactive> 245 </properties> 246 <activation> 247 <activeByDefault>false</activeByDefault> 248 </activation> 249 </profile> 250 </profiles> 251</project>
我们可以把很多公用的配置放在父模块中如打包环境配置,jar包版本依赖,那样的话子模块的pom.xml配置的东西就非常的少了,方便阅读。
这里父项目的pom.xml主要是配置了都需要的SpringBoot的相关引用,这样的话我们子项目完全不需要再重复引用了。另外其配置了profiles属性,这个属性是让我们区分多环境是打包哪些配置文件,其id参数就是我们的要打包环境的一个标识,比如我们打包测试环境我们只需要执行clean install -Ptest即可,-P后面的值即为这个id值,其中properties属性里面的列表是标识该环境生效的配置文件,属性里面的是SpringBoot配置文件后面的值,比如application-serviceproduct.properties其值就为serviceproduct
我们在看下kmall-common公共模块pom配置如下
1<?xml version="1.0" encoding="UTF-8"?> 2<project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>kmall</artifactId> 7 <groupId>cn.soboys.kmall</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 12 <artifactId>kmall-common</artifactId> 13 <dependencies> 14 <!--aop 切面--> 15 <dependency> 16 <groupId>org.springframework.boot</groupId> 17 <artifactId>spring-boot-starter-aop</artifactId> 18 </dependency> 19 <!--ip获取位置--> 20 <dependency> 21 <groupId>com.github.hiwepy</groupId> 22 <artifactId>ip2region-spring-boot-starter</artifactId> 23 </dependency> 24 <!--api 文档--> 25 <dependency> 26 <groupId>com.github.xiaoymin</groupId> 27 <artifactId>knife4j-spring-boot-starter</artifactId> 28 </dependency> 29 30 <!--数据库jar################--> 31 <!--mysql--> 32 <dependency> 33 <groupId>mysql</groupId> 34 <artifactId>mysql-connector-java</artifactId> 35 <scope>runtime</scope> 36 </dependency> 37 <!--mybatPlus--> 38 <dependency> 39 <groupId>com.baomidou</groupId> 40 <artifactId>mybatis-plus-boot-starter</artifactId> 41 </dependency> 42 <!--生成器依赖--> 43 <dependency> 44 <groupId>com.baomidou</groupId> 45 <artifactId>mybatis-plus-generator</artifactId> 46 </dependency> 47 <!--MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖:--> 48 <!--添加 模板引擎 依赖,MyBatis-Plus 支持 Velocity(默认)、 49 Freemarker、Beetl,用户可以选择自己熟悉的模板引擎, 50 如果都不满足您的要求,可以采用自定义模板引擎。--> 51 <dependency> 52 <groupId>org.freemarker</groupId> 53 <artifactId>freemarker</artifactId> 54 </dependency> 55 <!-- p6spy sql拦截调试--> 56 <dependency> 57 <groupId>p6spy</groupId> 58 <artifactId>p6spy</artifactId> 59 </dependency> 60 <!--数据库jar################--> 61 62 63 <!--微信小程序工具sdk--> 64 <dependency> 65 <groupId>com.github.binarywang</groupId> 66 <artifactId>weixin-java-miniapp</artifactId> 67 </dependency> 68 <!--微信支付工具sdk--> 69 <dependency> 70 <groupId>com.github.binarywang</groupId> 71 <artifactId>weixin-java-pay</artifactId> 72 </dependency> 73 <!--hutool 工具库--> 74 <dependency> 75 <groupId>cn.hutool</groupId> 76 <artifactId>hutool-core</artifactId> 77 <!--<exclusions> 78 <exclusion> 79 <groupId>cn.hutool</groupId> 80 <artifactId>hutool-setting</artifactId> 81 </exclusion> 82 </exclusions>--> 83 </dependency> 84 <dependency> 85 <groupId>cn.hutool</groupId> 86 <artifactId>hutool-json</artifactId> 87 </dependency> 88 <dependency> 89 <groupId>cn.hutool</groupId> 90 <artifactId>hutool-http</artifactId> 91 </dependency> 92 <dependency> 93 <groupId>cn.hutool</groupId> 94 <artifactId>hutool-extra</artifactId> 95 </dependency> 96 <dependency> 97 <groupId>cn.hutool</groupId> 98 <artifactId>hutool-crypto</artifactId> 99 </dependency> 100 <!--json 序列化--> 101 <dependency> 102 <groupId>com.alibaba</groupId> 103 <artifactId>fastjson</artifactId> 104 </dependency> 105 </dependencies> 106 107</project>
这里因为kmall父模块做了项目版本管理,所以这里只需要引入依赖就可以,依赖版本由父模块决定
然后我们在看一下kmall-bean模块pom
1<?xml version="1.0" encoding="UTF-8"?> 2<project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>kmall</artifactId> 7 <groupId>cn.soboys.kmall</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 12 <artifactId>kmall-bean</artifactId> 13 14 <dependencies> 15 <dependency> 16 <groupId>cn.soboys.kmall</groupId> 17 <artifactId>kmall-common</artifactId> 18 </dependency> 19 <!--参数校验--> 20 <dependency> 21 <groupId>org.springframework.boot</groupId> 22 <artifactId>spring-boot-starter-validation</artifactId> 23 </dependency> 24 </dependencies> 25 26</project>
依赖于公共模块,也单独引用了参数校验依赖
我们在看一下kmall-service模块pom
1<?xml version="1.0" encoding="UTF-8"?> 2<project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>kmall</artifactId> 7 <groupId>cn.soboys.kmall</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 <artifactId>kmall-service</artifactId> 12 13 <dependencies> 14 <dependency> 15 <groupId>cn.soboys.kmall</groupId> 16 <artifactId>kmall-common</artifactId> 17 </dependency> 18 <dependency> 19 <groupId>cn.soboys.kmall</groupId> 20 <artifactId>kmall-bean</artifactId> 21 </dependency> 22 </dependencies> 23</project>
依赖于公共模块,和bean模块
接下来我们看下两个主模块 kmall-api 有springboot启动类入口

ApiApplication是springboot启动类
1package cn.soboys.kmall.api; 2 3import cn.hutool.extra.spring.EnableSpringUtil; 4import org.mybatis.spring.annotation.MapperScan; 5import org.springframework.boot.SpringApplication; 6import org.springframework.boot.autoconfigure.SpringBootApplication; 7import org.springframework.context.ApplicationContext; 8 9 10 11@SpringBootApplication(scanBasePackages = {"cn.soboys.kmall"}) 12@MapperScan("cn.soboys.kmall.mapper") 13@EnableSpringUtil 14public class ApiApplication { 15 private static ApplicationContext applicationContext; 16 17 public static void main(String[] args) { 18 applicationContext = 19 SpringApplication.run(ApiApplication.class, args); 20 //displayAllBeans(); 21 } 22 23 24 /** 25 * 打印所以装载的bean 26 */ 27 public static void displayAllBeans() { 28 String[] allBeanNames = applicationContext.getBeanDefinitionNames(); 29 for (String beanName : allBeanNames) { 30 System.out.println(beanName); 31 } 32 } 33} 34
我们来看一下他的pom
1<?xml version="1.0" encoding="UTF-8"?> 2<project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>kmall</artifactId> 7 <groupId>cn.soboys.kmall</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 <artifactId>kmall-api</artifactId> 12 <packaging>war</packaging> 13 14 <dependencies> 15 <dependency> 16 <groupId>cn.soboys.kmall</groupId> 17 <artifactId>kmall-service</artifactId> 18 </dependency> 19 <!--jwt 认证--> 20 <dependency> 21 <groupId>com.auth0</groupId> 22 <artifactId>java-jwt</artifactId> 23 </dependency> 24 </dependencies> 25 26 <!--打包--> 27 <build> 28 <resources> 29 <resource> 30 <filtering>true</filtering> 31 <directory>src/main/resources</directory> 32 </resource> 33 </resources> 34 35 36 <plugins> 37 <plugin> 38 <groupId>org.apache.maven.plugins</groupId> 39 <artifactId>maven-compiler-plugin</artifactId> 40 <version>${maven.compiler.plugin.version}</version> 41 <configuration> 42 <source>${java.version}</source> 43 <target>${java.version}</target> 44 <encoding>${project.build.sourceEncoding}</encoding> 45 </configuration> 46 </plugin> 47 48 <plugin> 49 <groupId>org.apache.maven.plugins</groupId> 50 <artifactId>maven-resources-plugin</artifactId> 51 <version>${maven.resources.plugin.version}</version> 52 <configuration> 53 <encoding>${project.build.sourceEncoding}</encoding> 54 </configuration> 55 </plugin> 56 57 <plugin> 58 <groupId>org.apache.maven.plugins</groupId> 59 <artifactId>maven-jar-plugin</artifactId> 60 <version>${maven.jar.plugin.version}</version> 61 </plugin> 62 63 <!-- <plugin> 64 <artifactId>maven-war-plugin</artifactId> 65 <version>${maven-war-plugin.version}</version> 66 <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 –> 67 <packagingExcludes> 68 WEB-INF/lib/hutool-setting.jar, 69 </packagingExcludes> 70 </configuration> 71 </plugin>--> 72 73 <plugin> 74 <groupId>org.springframework.boot</groupId> 75 <artifactId>spring-boot-maven-plugin</artifactId> 76 <executions> 77 <execution> 78 <goals> 79 <goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中--> 80 </goals> 81 </execution> 82 </executions> 83 </plugin> 84 </plugins> 85 </build> 86</project>
这里pom做了一个打包的处理,我们需要打包时候只需要通过 IDEA 进行打包就可以啦


package进行打包war 发布到服务器就可以运行啦
我们再来看一下后台模块kmall-admin 有springboot启动类入口WebApplication
1@SpringBootApplication 2@MapperScan(value = {"cn.soboys.kmall.mapper","cn.soboys.kmall.sys.mapper","cn.soboys.kmall.security.mapper"},nameGenerator = UniqueNameGenerator.class) 3@ComponentScan(value = {"cn.soboys.kmall"},nameGenerator = UniqueNameGenerator.class) 4public class WebApplication { 5 private static ApplicationContext applicationContext; 6 7 public static void main(String[] args) { 8 applicationContext = 9 SpringApplication.run(WebApplication.class, args); 10 //displayAllBeans(); 11 } 12 13 14 /** 15 * 打印所以装载的bean 16 */ 17 public static void displayAllBeans() { 18 String[] allBeanNames = applicationContext.getBeanDefinitionNames(); 19 for (String beanName : allBeanNames) { 20 System.out.println(beanName); 21 } 22 } 23}
看下它的pom结构
1<?xml version="1.0" encoding="UTF-8"?> 2<project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>kmall</artifactId> 7 <groupId>cn.soboys.kmall</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 <packaging>war</packaging> 12 <artifactId>kmall-admin</artifactId> 13 14 <dependencies> 15 <dependency> 16 <groupId>cn.soboys.kmall</groupId> 17 <artifactId>kmall-service</artifactId> 18 </dependency> 19 <dependency> 20 <groupId>cn.soboys.kmall</groupId> 21 <artifactId>kmall-sys</artifactId> 22 </dependency> 23 </dependencies> 24 25 <!--打包--> 26 <build> 27 <resources> 28 <resource> 29 <filtering>true</filtering> 30 <directory>src/main/resources</directory> 31 </resource> 32 </resources> 33 34 35 <plugins> 36 <plugin> 37 <groupId>org.apache.maven.plugins</groupId> 38 <artifactId>maven-compiler-plugin</artifactId> 39 <version>${maven.compiler.plugin.version}</version> 40 <configuration> 41 <source>${java.version}</source> 42 <target>${java.version}</target> 43 <encoding>${project.build.sourceEncoding}</encoding> 44 </configuration> 45 </plugin> 46 47 <plugin> 48 <groupId>org.apache.maven.plugins</groupId> 49 <artifactId>maven-resources-plugin</artifactId> 50 <version>${maven.resources.plugin.version}</version> 51 <configuration> 52 <encoding>${project.build.sourceEncoding}</encoding> 53 </configuration> 54 </plugin> 55 56 <plugin> 57 <groupId>org.apache.maven.plugins</groupId> 58 <artifactId>maven-jar-plugin</artifactId> 59 <version>${maven.jar.plugin.version}</version> 60 </plugin> 61 62 <!-- <plugin> 63 <artifactId>maven-war-plugin</artifactId> 64 <version>${maven-war-plugin.version}</version> 65 <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 –> 66 <packagingExcludes> 67 WEB-INF/lib/hutool-setting.jar, 68 </packagingExcludes> 69 </configuration> 70 </plugin>--> 71 72 <plugin> 73 <groupId>org.springframework.boot</groupId> 74 <artifactId>spring-boot-maven-plugin</artifactId> 75 <executions> 76 <execution> 77 <goals> 78 <goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中--> 79 </goals> 80 </execution> 81 </executions> 82 </plugin> 83 </plugins> 84 </build> 85</project>
这里我配置文件中环境激活是根据父模块pom中配置走的 spring.profiles.active=@activeProfile@,@serviceactive@,@businessactive@
这里的值取值与父pom中环境打包配置

然后我们在打包前勾选需要打包的环境就可以了
这样基于SpringBoot+Maven 多模块项目的构建、运行、打包实战就完成啦,如果有什么疑问可以关注我公众猿小叔
