撸一个项目
前言
由于某些原因,我的springcloud系列是更不了了,先欠下一篇nacos教程
- 熬了几个夜终于把这个项目给撸了出来并上了服务器,不过有点惨的是没前端页面,而且服务器到4月份也就过期了,争取尽快把页面做出来。
- 本系列的开发环境 idea+mysql,框架是springboot。
-
本系列内容包括:
78729297552896464.jpg
(1)使用idea构建一个多模块项目,主要讲述分模块的原则和方式,和一些配置
(2)日志框架的使用与配置解析
(3)springsecurity 的从0到前后端分离的魔改及源码分析
(4)数据校验框架的使用与扩展
(5)quartz框架的使用与扩展
(6)MQ的在项目中的应用
我会尽力坚持更下去(最近是真的时间很紧,九点下班到家洗漱一下就十一点了,写不了多少东西)
如何使用maven+idea构建一个多模块项目
1.关于项目模块命名
对于命名规则我们参考springboot的风格,这样能使我们项目更规范;如果你观察过springboot工程的maven就不难发现,springboot的模块总是以spring-boot-starter开头,父模块为spring-boot-starter-parent。我们依样画葫芦,我的项目名叫poseidon(嘿嘿,有点骚气的名字);我项目模块划分为父模块poseidon-parent,公共模块poseidon-common,配置模块poseidon-core,安全模块poseidon-system,业务模块poseidon-web,定时任务模块poseidon-quartz,项目启动与打包的模块poseidon-center,以及后续可能扩展的模块poseidon-xxx....。
除了common 和core这两个基础模块,其他模块功能调用都通过接口interface,这样做的好处是方便模块的拆卸替换。比如我想剔除掉poseidon-quartz这个模块,在poseidon-web模块中只要实现其接口照样不影响业务模块的正常使用。(这里说一下题外话,其实对大部分人来说不必要去掌握多高深的设计模式,对设计模式的理解需要经验去沉淀的;在平时撸代码的时候我们只需要去遵守六大基本原则,并模仿spring的代码风格就能写出比较规整的代码,设计模式的目的也是为了去遵守六大基本原则,殊途同归)。
2.构建项目
新建文件夹:
image.png
用idea打开
右键项目 new module:
image.png
我喜欢用spring initializr 来构建模块,很方便,你也可以用maven工程来构建模块,区别不大。整体框架如下,poseidon-quartz后续讲解的时候再加上: 769005695068199960.jpg
我们构建完之后需要调整一下包结构和maven结构。
说明,因为我们项目是多模块采用maven依赖的的方式引入其他模块。所以,启动类要放在最外面,确保能扫描到其他模块的注解
而且各个模块包名要统一,springboot的依赖扫描才能起作用,注入到spring容器中。
好了,现在我们需要调整maven的结构,这里两个知识点--dependencyManagement和properties
首先,poseidon-parent
引入modules
packaging为pom
<modules>
<module>../poseidon-system</module>
<module>../poseidon-web</module>
<module>../poseidon-center</module>
<module>../poseidon-common</module>
<module>../poseidon-core</module>
</modules>
<groupId>com.muggle.poseidon</groupId>
<artifactId>poseidon-parent</artifactId>
<version>0.1.0.BUILD</version>
<description>波塞冬</description>
<packaging>pom</packaging>
pom继承自spring-boot-starter-parent
然后把它下面的包全删掉,只留下pom.xml。我们只需要使用它
说一下dependencyManagement的使用
如果你观察过不难发现springboot项目的一些依赖不需要指定版本,这就是说一下dependencyManagement的用法了,我们先在父pom中声名这个依赖并指定版本号,并不是真正的引入,在子模块中引入时就不需要指定版本号了,这样做的好处是版本号统一在父pom中管理。结合properties可以做到只需要改properties的版本号就能改整个项目的相关依赖的版本号,properties节点的用法类似于全局变量的感觉,你在节点用定义了一个值 然后你可以用${}方式引用这个值,下面贴出pom的结构:
<groupId>com.muggle.poseidon</groupId>
<artifactId>poseidon-parent</artifactId>
<version>0.1.0.BUILD</version>
<description>波塞冬</description>
<packaging>pom</packaging>
<modules>
<module>../poseidon-system</module>
<module>../poseidon-web</module>
<module>../poseidon-center</module>
<module>../poseidon-common</module>
<module>../poseidon-core</module>
</modules>
<name>poseidon</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<fastjson.version>1.2.53</fastjson.version>
<druid.vrsion>1.1.12</druid.vrsion>
<poseidon.version>0.1.0.BUILD</poseidon.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.vrsion}</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.muggle.poseidon</groupId>
<artifactId>poseidon-common</artifactId>
<version>${poseidon.version}</version>
</dependency>
<dependency>
<groupId>com.muggle.poseidon</groupId>
<artifactId>poseidon-core</artifactId>
<version>${poseidon.version}</version>
</dependency>
<dependency>
<groupId>com.muggle.poseidon</groupId>
<artifactId>poseidon-system</artifactId>
<version>${poseidon.version}</version>
</dependency>
<dependency>
<groupId>com.muggle.poseidon</groupId>
<artifactId>poseidon-web</artifactId>
<version>${poseidon.version}</version>
</dependency>
<dependency>
<groupId>com.muggle.poseidon</groupId>
<artifactId>poseidon-web-doc</artifactId>
<version>${poseidon.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.html</include>
<include>**/*.jsp</include>
<include>**/*.txt</include>
<include>**/*.jpg</include>
</includes>
<!--<filtering>false</filtering>-->
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<!--<filtering>false</filtering>-->
</resource>
</resources>
<!--<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>-->
</build>
注意我的build配置,我把springboot打包插件注释掉了,加了resources节点,resource节点是管控静态资源的。
现在配置其他模块
其他模块要注意的地方有配置relativePath指定父pom位置,否则打包插件无法找到父pom而报错。然后其他模块要继承父pom,除了poseidon-center需要配置打包插件,其他项目都不需要配置,下面贴出poseidon-center的pom,其他模块大同小异(poseidon-center 依赖项目需要所有的maven,打包插件就会把依赖添加进来)
<parent>
<groupId>com.muggle.poseidon</groupId>
<artifactId>poseidon-parent</artifactId>
<version>0.1.0.BUILD</version>
<relativePath>../poseidon-parent/pom.xml</relativePath>
</parent>
<groupId>com.muggle.poseidon</groupId>
<artifactId>poseidon-center</artifactId>
<version>0.1.0.BUILD</version>
<name>poseidon-center</name>
<description>波塞冬</description>
<properties>
<java.version>1.8</java.version>
<poseidon.version>0.1.0.BUILD</poseidon.version>
</properties>
<dependencies>
<dependency>
<groupId>com.muggle.poseidon</groupId>
<artifactId>poseidon-system</artifactId>
</dependency>
<dependency>
<groupId>com.muggle.poseidon</groupId>
<artifactId>poseidon-core</artifactId>
</dependency>
<dependency>
<groupId>com.muggle.poseidon</groupId>
<artifactId>poseidon-common</artifactId>
</dependency>
<dependency>
<groupId>com.muggle.poseidon</groupId>
<artifactId>poseidon-web-doc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName><!--打jar包去掉版本号-->
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.html</include>
<include>**/*.jsp</include>
<include>**/*.txt</include>
<include>**/*.jpg</include>
</includes>
<!--<filtering>false</filtering>-->
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<!--<filtering>false</filtering>-->
</resource>
</resources>
<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>
现在说一下打包,你可以用springboot的打包插件,就是center模块的spring-boot-maven-plugin 你在父pom上运行打包命令,在poseidon-center的 target里面就会打好你想要的包,示例(我这里idea装了个idea插件maven-helper,所以右键就行了):
512237178752422692.jpg 150512465012599660.jpg
这样打包的方式有一点不好,每一次我更新项目都要把整个jar包替换。我一般选择另外一种打包方式。利用artifacts功能,这样打出来来的jar包是很多个不可运行的jar包和一个启动jar包,这样我们每次更新项目只要更新服务器上的部分jar。利用beyondCompare这个工具比较一下哪个jar改变了就行。示例:
47275700731304652.jpg 111811721264714589.jpg 1eaf43107abefc4f1c1d69cab77cb0b.jpg 56296923068165939.jpg
把右边的东西一股脑往左边拖就行了:
656889387045126943.jpg
我们看下META-INF是用来干啥的:
585280219104250111.jpg 907663156325891039.jpg
显然,这个文件指定了版本号、启动类和依赖jar的位置。
接下来打包
image.png
然后选择build,会产生一个out的文件夹,里面打出来的包是这样的
image.png
启动jar包是这个
image.png
利用beyondCompare比较上传,第二次更新的时候就可以只上传更新过的jar就行
image.png
好了,就这么多,下回讲logback的配置和简单的封装。
构建多模块项目要注意的地方可以概括为以下几点:
1.除了common 和core模块,其他模块之间尽量解耦;
2.模块命名规范参照spring
3.配置好子模块的 <relativePath>,父模块的 <modules>,各个模块的resources节点,只在center(启动模块)上加打包插件,在父模块上运行打包命令
4.利用properties 和dependencyManagement节点进行版本控制。
5.建议使用artifacts来打包