本系列专题虽然是按教学的深度来定稿的,但在项目结构和代码组织方面是按生产系统的要求来书定的。在本章中主要介绍下基础开发框架的内容。后续所有章节的项目全是在本基础框架的基础上演进的。
工程结构介绍
- SpringbootSeries:父工程,定义一个通用Maven pom,主要用于版本管理;
- Framework:子工程组,包含两个Modules,主要是一些框架底层开发jar包;
- Springboot:子工程组,基于Springboot的项目,主要是集成不同的开发框架,比如springboot+mybatis等;
- Springcloud:子工程组,基于官方Springcloud的项目,主要是集成微服务组件,比如Gateway网关,ribbon负载均衡等;
- Alibaba Springcloud:子工程组,功能同Springcloud工程组差不多,主要是用阿里巴巴发展的组件实现微服务各功能部件;
springbootSeries父工程
版本依赖说明
类别 | 必选 | 可选 |
---|---|---|
基础框架 | jdk 17+ spring-boot-starter 3.2.4 spring-boot-starter-web 3.2.4 | spring-cloud 2023.0.1 spring-cloud-alibaba 2023.0.1.1 |
数据库 | mybatis-plus-spring-boot3-starter 3.5.6 druid-spring-boot-starter 1.2.22 mysql-connector-java 8.0.33 | |
工具包 | cn.hutool 5.8.27 org.projectlombok 1.18.30 | org.mapstruct 1.5.5.Final mapstruct-processor 1.5.5.Final framework-commons 1.0-SNAPSHOT |
日志 | slf4j 2.0.12 logback 1.4.14 | |
测试 | spring-boot-starter-test 3.2.4 springdoc-openapi-starter-webmvc-ui 2.4.0 spring-boot-starter-actuator 3.2.4 : runtime | spring-boot-devtools 3.2.4 |
JDK最低版本要求17,采用20, 21等也同样适用。
Maven scope说明
scope | 编译 | 测试 | 运行 | 打包 | 特殊说明 |
---|---|---|---|---|---|
compile | ✓ | ✓ | ✓ | ✓ | |
runtime | x | ✓ | ✓ | ✓ | |
test | x | ✓ | x | x | |
system | ✓ | ✓ | ✓ | x | 不依赖maven仓库,而是本地的jar包,不具备传递性 |
provided | ✓ | ✓ | x | x | 不具备传递性 |
import | x | x | x | x | 只能在 dependencyManagement下使用,且 type 需要为 pom,解决单继承问题 |
Maven配置说明
在本地测试时,需要把
<modules>
中的子模块做适当删减。
<?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>
<!--指定父工程:
1、其版本兼容情况可从:
https://spring.io/projects/spring-cloud 或
https://github.com/spring-cloud/spring-cloud-release/releases 上查询
2、springboot项目也可以用官方的工具生成
https://start.spring.io
-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
<relativePath/> <!--如果子工程出现parent.relativePath问题,需要加入这么一行-->
</parent>
<!--此工程声明为pom形式,供其它子模块引用-->
<groupId>com.korgs</groupId>
<artifactId>springbootSeries</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<!--子模块,一般为空,只在开发调试时建议放入一些子模块,为了便捷-->
<modules>
<module>springboot-base</module>
<module>framework-commons</module>
<module>framework-persistence</module>
<module>springboot-web</module>
<module>springcloud-eureka-server</module>
<module>springcloud-eureka-client</module>
<module>springcloud-eureka-server-with-security</module>
<module>springcloud-ribbon-server</module>
<module>springcloud-ribbon-client</module>
<module>springboot-mybatisplus</module>
<module>springcloud-consul-server</module>
<module>springcloud-consul-client</module>
<module>springcloud-consul-config</module>
<module>springcloud-api-gateway</module>
<module>springcloud-gateway-server</module>
<module>springcloud-admin-server</module>
<module>springcloud-admin-client</module>
<module>alibaba-nacos-config</module>
<module>alibaba-nacos-server</module>
<module>alibaba-nacos-client</module>
<module>alibaba-sentinel-server</module>
<module>alibaba-sentinel-client</module>
<module>springboot-openFeign-client</module>
<module>alibaba-sentinel-openFeign-client</module>
<module>springboot-common-config</module>
<module>springboot-redis</module>
<module>springboot-test</module>
<module>springboot-kafka</module>
<module>springboot-docker</module>
</modules>
<properties>
<!--设置javaSDK版本:语言级别要一致,然后匹配下idea中的在maven编译设置
JDK 21 = 65 JDK 17 = 61 JDK 8 = 52
-->
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-cloud.version>2023.0.1</spring-cloud.version>
<spring-cloud-alibaba.version>2023.0.1.0</spring-cloud-alibaba.version>
<!--开发中用到的三方工具包-->
<hutool.version>5.8.27</hutool.version>
<lombok.version>1.18.30</lombok.version>
<lombok.mapstruct.binding.version>0.2.0</lombok.mapstruct.binding.version>
<mapstruct.version>1.5.5.Final</mapstruct.version>
<framework-commons.version>1.0-SNAPSHOT</framework-commons.version>
<!--db-mysql-->
<mybatisplus.version>3.5.6</mybatisplus.version>
<druid.version>1.2.22</druid.version>
<mysql.version>8.0.33</mysql.version>
<!--测试相关-->
<junit.test.version>4.13.2</junit.test.version>
<openapi.restfultest.version>2.5.0</openapi.restfultest.version>
</properties>
<!--公共依赖-->
<dependencies>
<!--springboot-main-->
<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>
<!--springboot辅助工具-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--工具类,前提是必须先给IDEA安装Lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>annotationProcessor</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>com.korgs</groupId>
<artifactId>framework-commons</artifactId>
<version>${framework-commons.version}</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>${openapi.restfultest.version}</version>
</dependency>
</dependencies>
<!--可选依赖,这块的依赖不建议放太多-->
<dependencyManagement>
<dependencies>
<!--springboot-main:引入spring cloud的依赖,主要用来管理Spring Cloud生态各组件的版本-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--alibaba-springboot-main:引入spring cloud的依赖,主要用来管理alibaba Spring Cloud生态各组件的版本-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--数据库相关-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!--工具类-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<!--测试类-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<encoding>${project.build.sourceEncoding}</encoding>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<!-- additional annotation processor required as of Lombok 1.18.30 -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${lombok.mapstruct.binding.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
framework子工程组
这个工程中一共包含两个子模块, framework-persistence
依赖framework-commons
,framework-commons也可以单独引用。
framework-commons
:springboot框架底层功能封装;framework-commons
:mybatis数据库操作相关底层功能封装;
framework-commons模块
此模块主要是一些工具类
-
日志相关
- AccessLogInterceptor.java:web日志拦截器
- InterceptorRegister.java:拦截器注册类
- LogGenerator.java:日志工具类
-
Restful相关
- BaseResponse.java:基础restful响应对象
- ListResponse.java:继承BaseResponse.java,集合响应对象
- PageResponse.java:继承ListResponse.java,分页响应对象
- FileResponse.java:文件响应对象
- ResponseConst.java:响应常量类
-
servlet相关
- CorsConfig.java:跨域设置过滤器
-
工具类
- TranslatorUtil.java:对象转换工具类
- UUIDUtil.java:ID生成器
工程坐标
<groupId>com.korgs</groupId>
<artifactId>framework-commons</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
framework-persistence模块
持久化操作相关,暂时只封装了mybatis插件内容
-
底级框架封装
- DBEntity.java:数据实体基础类
- DBMetaObjectHandler.java:数据实体基础操作类
- MybatisPlusConfig.java:mybatis操作配置,主要集成了分页插件
-
分页数据对象相关
- PageParam.java:用于Controller层的分页查询参数对象
- PageQueryBo.java:用于Service层的分页查询参数对象
- PageBo.java:用于Service层的分页结果
- PageUtil.java:分页工具类
工程坐标
<groupId>com.korgs</groupId>
<artifactId>framework-persistence</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
springboot子工程组
springboot-base模块
此模块采用了maven独立配置,与父模块没有任何关系,只是为了说明如何简单的实现sprinboot应用。
Maven依赖配置
<?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.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
<relativePath/> <!--如果子工程出现parent.relativePath问题,需要加入这么一行-->
</parent>
<groupId>com.korgs</groupId>
<artifactId>springboot-base</artifactId>
<description>一个最基础的springboot工程框架</description>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--springboot-main-->
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
注意:pring-boot-maven-plugin必须配置,否则用maven -clear package打包后的jar包无法用 java -jar xxx.jar
来启动,原因是不包含依赖项。
application.properties配置
采用了两个文件,一个用于个性化配置,另一个用于基础配置。
- application.properties 个性化配置,每个项目的配置都不一样
spring.profiles.active = dev
spring.application.name=springbootBase
server.port=18080
- application-dev.properties 基本配置,这里的配置在任何项目中基本不会变化
#springboot Server
spring.aop.auto=true
spring.aop.proxy-target-class=true
# log4j
logging.level.root=INFO
logging.level.org.springframework.web=ERROR
#restful Server
server.compression.enabled=true
server.compression.mime-types=application/json,application/octet-stream
Restful测试地址
实现一个简单的Restful测试类,返回hello world
字符串。
@RestController
public class HelloWorldController {
private static final Log log = LogFactory.getLog(HelloWorldController.class);
@GetMapping("/helloworld")
public String helloWorld(){
log.info("I am busy to handle this request.");
return "hello world";
}
}
测试地址:http://localhost:18080/helloworld
springboot-web 模块
此模块的父模块为 springbootSeries。此模块可以做为一个模板工程,如果想开发新的工程时可以复制一份,然后修改部分配置即可,省去了从头写代码的麻烦。
- OpenAPIConfig:swagger3测试框架组件,详细可参考文章最后的源码
- SpringbootWebApplication:springboot启动类
@Slf4j
@SpringBootApplication(scanBasePackages = {"com.korgs", "cn.hutool.extra.spring"})
@Configuration
@EnableConfigurationProperties
@ServletComponentScan
@RestController
public class SpringbootWebApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebApplication.class, args);
}
@GetMapping("/helloworld")
public BaseResponse helloWorld(){
log.info(LogGenerator.trackLog()
+ "msg="+ "I am busy to handle this request.");
return BaseResponse.success("hello world");
}
}
Maven依赖配置
<?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>com.korgs</groupId>
<artifactId>springbootSeries</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>springboot-web</artifactId>
<description>带有日志和基础组件的springbootweb工程</description>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
application.properties配置
采用了两个文件,一个用于个性化配置,另一个用于基础配置。
- application.properties 个性化配置,每个项目的配置都不一样
spring.profiles.active = dev
spring.application.name=springbootWeb
server.port=18081
management.endpoints.web.exposure.include = *
management.endpoint.health.show-details=always
- application-dev.properties 基本配置,这里的配置在任何项目中基本不会变化
#springboot Server
spring.aop.auto=true
spring.aop.proxy-target-class=true
# log4j
logging.config=classpath:log4j2.xml
logging.level.root=INFO
logging.level.org.springframework.web=ERROR
#restful Server
server.compression.enabled=true
server.compression.mime-types=application/json,application/octet-stream
#swagger
springdoc.api-docs.enabled=true
springdoc.api-docs.path=/api-schema
swagger-config.group = default-group
swagger-config.description= The following is a restful-api list of {} application, and you can browse or test them to determine if they are working as you expect.
swagger-config.version=V1.0
swagger-config.urlPattern=/**
swagger-config.base-package=com.korgs
swagger-config.authorization-key-name=token
swagger-config.wiki = https://korgs.blog.csdn.net/
源码运行和测试方法
源码下载
着手开发属于自己的第一个Intellij-platform plugin插件程序(三)配套源码
源码编译
因采用了父子结构,所以在运行相应模块的SpringbootApplication.java启动类之前,要先
1 . 先在springbootSeries
模块(即最外层的父工程)中执行mvn install
,把pom.xml缓存到本地;
2. 再依次在framework-commons
和framework-persistence
模块中执行mvn install
。以上三个模块的执行顺序不能弄错,且只执行一次即可。
- 执行相应模块的 SpringbootApplication.java 启动类启动服务。
模块测试
可以直接通过浏览器测试,但建议通过swagger进行测试。访问地址为:http://localhost:18080/swagger-ui.html
,18080为spingboot应用的端口号,可以application.properties文件中查找