文章目录
一、SpringBoot聚合项目
1、创建父工程
新建工程,选择Spring initializer
填写好项目名称等
不勾选任何依赖,最后选择好项目存储位置,点击创建
删除不必要的文件
保留父工程项目必要的文件
.gitignore
:分布式版本控制系统git的配置文件,意思为忽略提交
mvnw
:全名是maven wrapper的文件,作用是在maven-wrapper.properties文件中记录你要使用的maven版本,当用户执行mvnw clean 命令时,发现当前用户的maven版本和期望的版本不一致,那么就下载期望的版本,然后用期望的版本来执行mvn命令,比如mvn clean命令。
.mvn
文件夹:存放mvnw相关文件
mvnw.cmd
:执行mvnw命令的cmd入口。其中mvnw文件适用于Linux(bash),mvnw.cmd适用于Windows 环境。
.iml
文件:intellij idea的工程配置文件,里面包含当前project的一些配置信息,如模块开发的相关信息,比如java组件,maven组件,插件组件等,还可能会存储一些模块路径信息,依赖信息以及一些别的信息。
.idea
文件夹:存放项目的配置信息,包括数据源,类库,项目字符编码,历史记录,版本控制信息等。pom.xml
:项目对象模型(核心重要)
2、创建子工程
新建Module
选择Spring Initializer,也可直接选择新建空Maven项目
设置子模块信息
类似可以创建多个子模块
3、父子模块配置文件设置
3.1 父模块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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--全局定义springboot父项目版本号-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!--项目描述-->
<groupId>com.zstu</groupId>
<artifactId>lamp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>intelligent-lamp</name>
<description>智能灯项目</description>
<!--packageing需要指定为pom-->
<!--项目的打包类型:pom、jar、war
packing默认是jar类型,
pom 父类型都为pom类型
jar 内部调用或者是作服务使用
war - 需要部署的项目-->
<packaging>pom</packaging>
<!--子工程目录,每添加一个model,需要将子工程的model名注册到此-->
<modules>
<module>childserver</module>
</modules>
<!--定义springcloud使用版本号等属性信息-->
<properties>
<java.version>1.8</java.version>
<lombok.version>1.18.12</lombok.version>
<fastjson.version>1.2.76</fastjson.version>
</properties>
<!--引入全体项目都需要的父依赖,引入后,子项目不需要引入,继承父项目就可以-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!--全局管理依赖,并不会引入具体依赖-->
<!--只是依赖的声明,并不实现引入,因此子项目需要显式的声明需要用的依赖,这样做的好处是可以方便进行版本控制-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
3.2 子模块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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 确认父子工程继承关系 -->
<parent>
<!--父工程 groupId-->
<groupId>com.zstu</groupId>
<!--父工程 artifactId-->
<artifactId>lamp</artifactId>
<!--父工程 版本-->
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.zstu</groupId>
<artifactId>childserver</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>childserver</name>
<description>子工程</description>
<!--这里由父工程控制版本信息-->
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
<build>
<!--重命名打包-->
<finalName>child-module</finalName>
<plugins>
<!--
Maven区别对待Java代码文件和资源文件,maven-compiler-plugin用来编译Java代码
maven-resources-plugin则用来处理资源文件
-->
<!--如果子项目并不是单独的springboot项目,不能独立启动,则父工程不能使用此插件,应该放在能启动服务的子项目中-->
<!--boot项目使用boot打包插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 如果没有该配置,devtools不会生效 -->
<!-- 指定该Main Class为全局的唯一入口 -->
<mainClass>com.zstu.childserver.ChildserverApplication</mainClass>
<layout>ZIP</layout>
<!--分类器:可执行jar包重命名-->
<classifier>exec</classifier>
</configuration>
<executions>
<execution>
<goals>
<!--可以把依赖的包都打包到生成的可执行Jar包中-->
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
4、工程打包
4.1 打包流程
创建好基础的web服务后,首先需要在父工程的maven管理下进行mvn clean
,之后进行mvn install
,最后可以进行子服务的打包mvn package
4.2 多项目打包常见问题
- 如果子项目并不是单独的springboot项目,不能独立启动,则父工程不能使用此插件,应该放在能启动服务的子项目中
- 对于多项目,springboot启动类的默认扫描路径是该类所在的包下面的所有java类,若访问的为不同模块,则需要配置扫描包,例如我的配置
@SpringBootApplication(scanBasePackages = "com.zstu.*")
- 若子项目需要依赖另一子项目文件,则需要在
pom.xml
中配置<dependency>
依赖进行引入 - 聚合项目存在第二个模块依赖第一个模块,需要引入jar包,编码调试一切正常。但
mvn install
第二个项目的时候会提示找不到jar包里的类。原因 : spring-boot-maven-plugin打包出来的jar是不可依赖的,所以只需要在被依赖的包(也就是第一个模块中)去掉spring-boot-maven-plugin即可打包成功
5、Spring打包插件详解
Spring Boot Maven plugin的5个Goals
- spring-boot:repackage:默认goal。在mvn package之后,再次打包可执行的jar/war,同时保留mvn package生成的jar/war为.origin
- spring-boot:run:运行Spring Boot应用
- spring-boot:start:在mvn integration-test阶段,进行Spring Boot应用生命周期的管理
- spring-boot:stop:在mvn integration-test阶段,进行Spring Boot应用生命周期的管理
- spring-boot:build-info:生成Actuator使用的构建信息文件build-info.properties
一旦 spring-boot-maven-plugin
被添加到 pom.xml
,就可以使用goal spring-boot:repackage
生成可执行文件。可以通过pom.xml
文件的packaging
配置节告诉插件生成的是jar
包还是war
包.
<?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">
<!-- ... -->
<packaging>war</packaging>
<!-- ... -->
<dependencies>
<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> <!-- 改成provided之后,tomcat 就不会打包进war文件 -->
</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>
二、多环境配置与切换
1、介绍
多环境是最常见的配置隔离
方式之一,可以根据不同的运行环境提供不同的配置信息来应对不同的业务场景,在SpringBoot
内支持了多种配置隔离的方式,可以激活单个或者多个配置文件
2、spring自带方式切换环境
2.1 简单实现步骤
首先创建几个不同环境的配置文件,application-{profile}.properties(.yaml/.yml)
,其中profile
可以根据自己的需求来定义,这里我定义了三种环境(开发、测试和生产环境)
在application-dev.yml
等文件写入相应的信息
#开发环境
server:
port: 8081
在application.yml
设置环境
spring:
profiles:
active: dev
最后运行、部署就会按照对应的环境运行
当然这里也可以把多文件内容放在同一个文件中,即application.yml
(不推荐)
# 开发环境
server:
port: 8081
spring:
profiles: dev
---
# 测试环境
server:
port: 8082
spring:
profiles: test
---
# 生产环境
server:
port: 8083
spring:
profiles: prod
---
## 用来动态选择 开发、测试、生产的运行环境的配置文件的
spring:
profiles:
active: dev
2.2 其他方式激活profiles
- 命令行方式
nohup java -jar child-module-exec.jar --spring.profiles.active=dev > child-module-exec.log 2>&1 &
- 系统变量方式
系统变量的方式适用于系统下所部署统一环境的SpringBoot
应用程序,如统一部署的都是prod
环境的应用程序。编辑环境变量配置文件/etc/profile
,添加名为SPRING_PROFILES_ACTIVE
的环境变量。注意:-D
方式设置Java系统属性
要在-jar
前定义。
# spring 环境激活
export SPRING_PROFILES_ACTIVE=dev
- Java系统属性方式
Java系统属性方式
也是一种外部配置的方式,在执行java -jar
命令时可以通过-Dspring.profiles.active=test
的方式进行激活指定的profiles
列表
nohup java -Dspring.profiles.active=dev -jar child-module-exec.jar > child-module-exec.log 2>&1 &
- 配置文件方式(2.1已介绍)
上述四种方式的优先级为:命令行方式 > Java系统属性方式 > 系统变量方式 > 配置文件方式
3、idea+maven多环境配置
3.1 配置步骤
首先仍然和2.1一样创建好几种不同的环境配置,但是application.yml
需要修改部分内容
spring:
profiles:
# 如果不添加引号的话,程序启动无法识别,会报错导致启动失败
active: '@env@'
在子模块的pom.xml
中配置,filtering配置必须设置为true,这样Filtering 默认的过滤符号就从 ${*}
改为 @...@
<build>
<!--重命名打包-->
<finalName>child-module</finalName>
<plugins>
<!--
Maven区别对待Java代码文件和资源文件,maven-compiler-plugin用来编译Java代码
maven-resources-plugin则用来处理资源文件
-->
<!--如果子项目并不是单独的springboot项目,不能独立启动,则父工程不能使用此插件,应该放在能启动服务的子项目中-->
<!--boot项目使用boot打包插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
</configuration>
<executions>
<execution>
<goals>
<!--可以把依赖的包都打包到生成的可执行Jar包中-->
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<!-- 指定配置文件的位置 -->
<directory>src/main/resources</directory>
<includes>
<!-- 读取resources下的所有文件,include表示指定文件内的,相对的还有excludes ,排除其下的文件 -->
<include>**/*</include>
</includes>
<!-- 开启替换标签,比如我们的'@env'就是通过这个替换的 -->
<filtering>true</filtering>
</resource>
</resources>
</build>
因为是多模块项目,这里将Profiles配置放在了父模块的pom.xml
中
<!--配置不同的profile,对应不同的生产环境-->
<profiles>
<profile>
<!--开发-->
<id>dev</id>
<activation>
<!--默认开发环境-->
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<!--自定义的变量名称env作为标签,标签内是我们配置文件不同环境的后缀 -->
<env>dev</env>
</properties>
</profile>
<profile>
<!--生产-->
<id>prod</id>
<properties>
<env>prod</env>
</properties>
</profile>
<profile>
<!--测试-->
<id>test</id>
<properties>
<env>test</env>
</properties>
</profile>
</profiles>
此时在Idea的右侧可以发现Profiles属性,选择相应的环境,子模块打包即为相应环境的配置
3.2 联动原理
- 首选
pom.xml
配置了多环境配置 - IDEA指定勾选 和 服务器端
mvn -P test
指定maven的profile对应的ID - 服务启动/打包编译时候,便根据maven的profile对应的ID 找到对应的标签,并加载到了内部的标签
- 标签中的中的下,一定是设置为true,开启了pom和配置文件之间的通道
- 对应的标签中加载到的标签中的自定义key - value拿上,去找到
application.yml
中的@XXX@ 或 ${}表达式 - spring.profiles.active=@env@,并根据key为env,做了value的替换,最终编译完成,
application.yml
中的 spring.profiles.active=dev - 应用在启动中,就根据 spring.profiles.active=dev,成功加载上了
application-dev.yml
文件 - 最终,完成了 maven的profile和 springboot的profile的联动替换。