记Spring搭建功能完整的个人博客「Oyster」全过程[其二] Idea中Maven+SpringBoot多模块项目开发的设计和各种坑(模块间依赖和打包问题)
大家好嘞,今天闲着没事干开写写博客,记录一下Maven+SpringBoot的多模块设计和遇到的坑。
多模块设计
简单说明一下截止目前的需求:
- 需要RESTful API:对文章、标签、分类和评论等的CRUD
- 要前台展示: 首页、归档、文章具体页等
- 后台管理:添加文章、新增标签之类
简单分析可以简单设计一个模块来组织代码,比如就叫oyster-blog。
但显然有个问题,这么设计会让代码比较混乱,比如我不能在同一个类中处理所有的请求,也不能分成三个类分别实现这三个功能。
比较好的设计是分成三个包,然后各个包内细化各个功能。
这么做的话,不太方便团队开发。一堆人一起写一个模块,管理起来有些麻烦。
比如突然新增一个特性,牵扯一堆东西。大家一起写的话,最后合并代码说不定还会冲突。
所以我们来稿多模块吧。
但不方便的地方还是存在,比如突然有一天我的前台展示挂掉了。
这种情况下,老板或者我个人甚至想让api模块不受影响,继续运行。
这可咋整?
这种情况我们貌似可以做微服务了。(猜测这样多模块设计过渡到微服务是轻松的,还没想做这个呢)
那么就有一个多模块的设计:
- oyster-common
提供公共的访问数据库的接口,工具类(比如分析请求的工具,时间处理) - oyster-api
提供RESTful API - oyster-front
提供前台展示 - oyster-back
后台管理
Maven多模块构建的细节
最终模块长这样:

首先新建一个maven工程,然后删除文件,只剩pom.xml。具体pom配置下来再说。
新建api、common和front模块:
- 组织名就填组织名,例:org.tanglizi
- artifact填项目名,例:oyster
- 包名换成具体模块名,例:org.tanglizi.oyster.api
父模块oyster的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">
<modelVersion>4.0.0</modelVersion>
<groupId>org.tanglizi</groupId>
<artifactId>oyster</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<!-- 注意此处 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/>
</parent>
<!-- 注意此处 -->
<modules>
<module>oyster-common</module>
<module>oyster-api</module>
<module>oyster-front</module>
<module>oyster-runner</module>
</modules>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<!-- plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins -->
<!-- 注意此处 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<skipTests>true</skipTests> <!--默认关掉单元测试 -->
</configuration>
</plugin>
</plugins>
</build>
</project>
子模块oyster-api
<?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>
<!-- 注意此处 -->
<parent>
<groupId>org.tanglizi</groupId>
<artifactId>oyster</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.tanglizi</groupId>
<artifactId>oyster-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>oyster-api</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.tanglizi</groupId>
<artifactId>oyster-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<!-- plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins -->
</build>
</project>
子模块oyster-common
<?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>
<!-- 注意此处 -->
<parent>
<groupId>org.tanglizi</groupId>
<artifactId>oyster</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.tanglizi</groupId>
<artifactId>oyster-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>oyster-common</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<!-- plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins -->
</build>
</project>
oyster-front
<?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>
<!-- 注意此处 -->
<parent>
<groupId>org.tanglizi</groupId>
<artifactId>oyster</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.tanglizi</groupId>
<artifactId>oyster-front</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>oyster-front</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.tanglizi</groupId>
<artifactId>oyster-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- scope>compile</scope -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.vladsch.flexmark</groupId>
<artifactId>flexmark-all</artifactId>
<version>0.42.6</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<!-- plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins -->
</build>
</project>
oyster-runner
<?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>
<!-- 注意此处 -->
<parent>
<groupId>org.tanglizi</groupId>
<artifactId>oyster</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.tanglizi</groupId>
<artifactId>oyster-runner</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>oyster-runner</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.tanglizi</groupId>
<artifactId>oyster-front</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.tanglizi</groupId>
<artifactId>oyster-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.tanglizi</groupId>
<artifactId>oyster-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!--scope>compile</scope-->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--
注意此处
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project oyster-front: Compilation failure: Compilation failure:
[ERROR] /home/tanglizi/IdeaProjects/oyster/oyster-front/src/main/java/org/tanglizi/oyster/controllers/SearchController.java:[8,40] package org.tanglizi.oyster.dto.entities does not exist
-->
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Maven+SpringBoot多模块的细节
待续
记Spring搭建功能完整的个人博客「Oyster」全过程[其二] Idea中Maven+SpringBoot多模块项目开发的设计和各种坑(模块间依赖和打包问题)的更多相关文章
- 记Spring搭建功能完整的个人博客「Oyster」全过程[其一] 整体思路:需求、架构及技术要求
一两个星期前正在了解Linux内核,看得有点累,突然想趁着五一放假写个博客学学spring. 由于没有在一开始下定决心写这个博客系统,所以我又没记录一开始的分析过程.这都是写了一个星期之后的思路了. ...
- Java EE 学习(9):IDEA + maven + spring 搭建 web(5)- 博客文章管理
转载:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生) . 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) Jav ...
- python drf+xadmin+react+dva+react-native+sentry+nginx 搭建前后端分离的博客完整平台
前言: 经过差不多半年的开发,搭建从前端到服务器,实现了前后端分离的一个集PC端.移动端的多端应用,实属不易,今天得空,好好写篇文章,记录这些天的成果.同时也做个分享. 演示网站地址: http:// ...
- LNMP环境搭建之php安装,wordpress博客搭建
LNMP环境搭建之php安装,wordpress博客搭建 一.介绍: 1.什么是CGI CGI全称是"通用网关接口"(Common Gateway Interface),HTTP服 ...
- 搭建自己的 github.io 博客
1.前言 github.io 是基于 Github 的 repo 管理,这意味着咱们对其是有绝对的控制,这个跟放在第三方的平台比,可控性要好太多. 使用 github pages 服务搭建博客的好处有 ...
- 搭建minima主题的github博客网站
layout: post title: "搭建minima主题的github博客网站" date: 2019-04-20 19:20:20 +0800 --- 作者:吴甜甜 个人博 ...
- HHvm Apache 2.4 Nginx建站环境搭建方法安装运行WordPress博客
HHvm Apache 2.4 Nginx建站环境搭建方法安装运行WordPress博客 VPS主机 2014年06月02日 17:20 评论» 文章目录 Debian上安装 Ce ...
- 初学者入门:使用WordPress搭建一个专属自己的博客
体验简介 阿里云云起实验室提供相关实验资源,点击前往 场景将提供一台基础环境为CentOS 的ECS(云服务器)实例,这台服务器上已经内置LAMP环境.我们将会在这台服务器上安装 WordPress ...
- Mac 上搭建基于 Hexo + GitHub 个人博客
环境配置 本人电脑系统:macOS Node.js 生成静态页面.安装Node.js Git 用于将本地 Hexo 内容提交到 Github.Xcode自带Git(前提:macOS已经安装了Xcode ...
随机推荐
- F - Count the Colors
F - Count the Colors ZOJ - 1610 思路:调了一个小时,但是发现自己线段树木有写错,颜色统计出了错误.但是不明白自己颜色统计为什么错了. 求大佬指点迷津.思路很简单,就 ...
- SWT中嵌入Swing的JTextFeild却不能编辑
SWT中嵌入Swing的JTextFeild却不能编辑 学习了:http://www.iteye.com/problems/49487 膜拜一下 org 竟然有这样的坑,需要在中间添加一个JApp ...
- Fitnesse中的symbols和variables
1.symbols 主要在表间传递信息,作用于一个page中,类似于局部变量 SaveRecordInDatabase name date =key? Bob today bobKey Bill la ...
- JavaScript高级特性之原型
JavaScript的原型 原型prototype属性仅仅适用于函数对象(这里的函数对象是自己为了理解更好定义的,普通对象是没有原型属性的) 1.研究函数原型: <script type=&qu ...
- Swift - 可编辑表格样例(可直接编辑单元格中内容、移动删除单元格)
(本文代码已升级至Swift3) 本文演示如何制作一个可以编辑单元格内容的表格(UITableView). 1,效果图 (1)默认状态下,表格不可编辑,当点击单元格的时候会弹出提示框显示选中的内容 ...
- day63-webservice 06.在web项目中发布以类的形式发布webservice
真正用的时候都是需要部署在WEB服务器里面. 不能写主函数来发布了,需要借助于我们WEB. 4.配置web.xml, <!DOCTYPE web-app PUBLIC "-//Sun ...
- php Aes 128位算法
<?php class Mcrypt { private static $key = "fsdjfojojodjiovjojgfosdjfiojio"; private st ...
- hihoCoder-1633 ACM-ICPC北京赛区2017 G.Liaoning Ship’s Voyage 线段与三角形规范相交
题面 题意:给你一个20*20的地图,起点(0,0),终点(n-1,n-1),有障碍的点为‘#’,每次可以向8个方向走一步,还给了一个三角形,除了障碍以外,到这8个方向上的点的线段如果没有与三角形相交 ...
- 如何卸载Win10自带Xbox、人脉、天气等应用?
Win10中的Modern应用一般可在右键菜单中进行卸载,不过某些自带的Modern应用,比如Xbox.天气.人脉.照片等应用是无法在右键菜单中进行卸载的.如果你有卸载这些应用的需求,可参考下面的方法 ...
- POJ 3620 DFS
题意: 给你n*m的矩形,有k个坏点 问最大坏点连通块的坏点数. 一发水题.. 裸的DFS // by SiriusRen #include <cstdio> #include <a ...