IT评测·应用市场-qidao123.com
标题:
开源项目芋道源码剖析 [开篇]
[打印本页]
作者:
海哥
时间:
2025-1-22 21:35
标题:
开源项目芋道源码剖析 [开篇]
文章首发于我的博客:https://blog.liuzijian.com/post/source-code-about-ruoyi-vue-pro.html
1.弁言
芋道(又名yudao,ruoyi-vue-pro)是一个基于spring-boot框架的单体Java后端开源项目,拥有基于RBAC模子的组织架构管理、CRM、ERP、商城、代码天生、AI等多个功能模块。封装了多租户、数据权限、工作流、OAuth,邮件、短信、定时任务、日志、链路追踪等多种技术和业务组件。其在GitHub上的地址是:
https://github.com/YunaiV/ruoyi-vue-pro
因工作中会用到这个框架,为了更好的定制和更新功能,所以决定把它的源码核心部门都读一遍,博客持续更新,边学习,边输出,做知识积累整理输出。对学过的做过的东西,有个痕迹与存档,可以随时做归纳总结。
本文基于2.4.0-jdk8-SNAPSHOT版本的源码。
2.项目总体结构
项目基于传统的maven构建,大致结构如下,整个项目是多模块结构,分为1个父模块和多个子模块。
ruoyi-vue-pro [yudao]
│
├── yudao-dependencies
│ └── pom.xml
│
├── yudao-framework
│ ├── yudao-common
│ │ └── src
│ │ └── pom.xml
│ ├── yudao-spring-boot-starter-biz-xxxxxxx
│ │ └── src
│ │ └── pom.xml
│ ├── yudao-spring-boot-starter-xxxxxxx
│ │ └── src
│ │ └── pom.xml
│ └── pom.xml
│
│── yudao-module-aaa
│ ├── yudao-module-aaa-api
│ │ └── src
│ │ └── pom.xml
│ ├── yudao-module-aaa-biz
│ │ └── src
│ │ └── pom.xml
│ └── pom.xml
│
│── yudao-module-bbb
│ ├── yudao-module-bbb-api
│ │ └── src
│ │ └── pom.xml
│ ├── yudao-module-bbb-biz
│ │ └── src
│ │ └── pom.xml
│ └── pom.xml
│
│── yudao-server
│ └── src
│ └── pom.xml
│
└── pom.xml
复制代码
3.模块的结构,功能和依赖关系
3.1 root
最外层的/pom.xml作为root模块的配置,通过包罗了yudao-framework,yudao-module-xxxxxx,yudao-server,yudao-dependencies等浩繁模块。
<?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">
......
<modules>
<module>yudao-dependencies</module>
<module>yudao-framework</module>
<module>yudao-server</module>
<module>yudao-module-system</module>
<module>yudao-module-infra</module>
</modules>
......
</project>
复制代码
root模块通过引用负责统一依赖版本的模块yudao-dependencies来将依赖的版本号传递给所有子模块,从而统一整个项目的依赖版本
<dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-dependencies</artifactId>
<version>${revision}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
复制代码
root模块使用${revision}来设置自身的版本号,子模块的如果也设置为${revision}的话,就继承了root模块的版本号了,子模块的子模块也是一样的道理,这样整个工程所有子孙模块的版本号就都统一起来了,需要升级版本时,只需要在root模块的pom.xml文件中,把内里的版本号一改,整个工程所有子孙模块的版本号便全部跟着变了。
例:
/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">
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
... ...
<properties>
<revision>2.4.0-jdk8-SNAPSHOT</revision>
</properties>
</project>
复制代码
yudao-module-system/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">
<parent>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<modules>
<module>yudao-module-system-api</module>
<module>yudao-module-system-biz</module>
</modules>
<artifactId>yudao-module-system</artifactId>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<description>
system 模块下,我们放通用业务,支撑上层的核心业务。
例如说:用户、部门、权限、数据字典等等
</description>
</project>
复制代码
yudao-module-system/yudao-module-system-api/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">
<parent>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-system</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-system-api</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
system 模块 API,暴露给其它模块调用
</description>
......
</project>
复制代码
通过插件org.codehaus.mojo:flatten-maven-plugin来防止不必要的依赖传递
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${spring.boot.version}</version>
</path>
<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>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>${flatten-maven-plugin.version}</version>
<configuration>
<flattenMode>oss</flattenMode>
<updatePomFile>true</updatePomFile>
</configuration>
<executions>
<execution>
<goals>
<goal>flatten</goal>
</goals>
<id>flatten</id>
<phase>process-resources</phase>
</execution>
<execution>
<goals>
<goal>clean</goal>
</goals>
<id>flatten.clean</id>
<phase>clean</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
复制代码
3.2 yudao-dependencies
这个模块内仅有一个pom.xml文件,该模块的作用仅仅是统一整个项目的依赖版本,因为yudao-dependencies模块没有指定,因此不能从父(即root)模块继承${revision},需要在自己的内里维护自己的${revision}版本供自己引用,版本号的值一样平常要与root模块中的版本号要保持一致。
{% note warning %}
yudao-dependencies模块并不是root模块的子模块,因为如果root模块成了yudao-dependencies的父模块的同时还引用了子模块yudao-dependencies的话,就会导致循环引用,因此yudao-dependencies没有指定,只是由root模块通过包罗进去举行代管,root模块构建时,yudao-dependencies会一并构建。
<?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">
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-dependencies</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
... ...
<properties>
<revision>2.4.0-jdk8-SNAPSHOT</revision>
</properties>
... ...
</project>
复制代码
yudao-dependencies内里只有一个pom.xml文件,其使用声明了整个项目所需要的依赖,并被root模块引入,从而统一整个工程的依赖版本。
yudao-dependencies不但通过引用springframework,spring-boot-dependencies等type为pom的依赖项来继承第三方框架的版本,还规定了项目自身封装的一些框架(yudao-framework)的版本号。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring.framework.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-bom</artifactId>
<version>${spring.security.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-data-permission</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-common</artifactId>
<version>${revision}</version>
</dependency>
... ...
</dependencies>
</dependencyManagement>
复制代码
通过插件org.codehaus.mojo:flatten-maven-plugin来防止不必要的依赖传递
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>${flatten-maven-plugin.version}</version>
<configuration>
<flattenMode>bom</flattenMode>
<updatePomFile>true</updatePomFile>
</configuration>
<executions>
<execution>
<goals>
<goal>flatten</goal>
</goals>
<id>flatten</id>
<phase>process-resources</phase>
</execution>
<execution>
<goals>
<goal>clean</goal>
</goals>
<id>flatten.clean</id>
<phase>clean</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
复制代码
3.3 yudao-framework
该模块内主要是需要用到的公共依赖和一些对常用框架和功能组件的封装,大致结构如下
yudao-framework
│
│── yudao-common
│ ├─ src
│ │ └─ main
│ │ └─ java
│ │ └─ cn.iocoder.yudao.framework.common
│ │ └─ core
│ │ └─ enums
│ │ └─ exception
│ │ └─ pojo
│ │ └─ util
│ │ └─ validation
│ │
│ └─ pom.xml
│
│── yudao-spring-boot-starter-xxxxxx
│ ├─ src
│ │ └─ main
│ │ ├─ java
│ │ | ├─ cn.iocoder.yudao.framework.xxxxxx
│ │ | │ └─ config
│ │ | │ └─ core
│ │ | │ └─ aaa
│ │ | │
│ │ | └─ bbb.ccc.ddd
│ │ │
│ │ └─ resources
│ │ └─ META-INF.spring
│ │ └─ org.springframework.boot.autoconfigure.AutoConfiguration.imports
│ │
│ └── pom.xml
│
└── pom.xml
复制代码
yudao-framework下没有其他依赖,只是简单的将所有封装的组件聚合起来
yudao-framework/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>
<parent>
<artifactId>yudao</artifactId>
<groupId>cn.iocoder.boot</groupId>
<version>${revision}</version>
</parent>
<packaging>pom</packaging>
<modules>
<module>yudao-common</module>
<module>yudao-spring-boot-starter-mybatis</module>
<module>yudao-spring-boot-starter-redis</module>
<module>yudao-spring-boot-starter-web</module>
<module>yudao-spring-boot-starter-security</module>
<module>yudao-spring-boot-starter-websocket</module>
<module>yudao-spring-boot-starter-monitor</module>
<module>yudao-spring-boot-starter-protection</module>
<module>yudao-spring-boot-starter-job</module>
<module>yudao-spring-boot-starter-mq</module>
<module>yudao-spring-boot-starter-excel</module>
<module>yudao-spring-boot-starter-test</module>
<module>yudao-spring-boot-starter-biz-tenant</module>
<module>yudao-spring-boot-starter-biz-data-permission</module>
<module>yudao-spring-boot-starter-biz-ip</module>
</modules>
<artifactId>yudao-framework</artifactId>
<description>
该包是技术组件,每个子包,代表一个组件。每个组件包括两部分:
1. core 包:是该组件的核心封装
2. config 包:是该组件基于 Spring 的配置
技术组件,也分成两类:
1. 框架组件:和我们熟悉的 MyBatis、Redis 等等的拓展
2. 业务组件:和业务相关的组件的封装,例如说数据字典、操作日志等等。
如果是业务组件,Maven 名字会包含 biz
</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
</project>
复制代码
yudao-common模块封装了一些项目公共的枚举类,非常类,公共的实体类,和一些工具类,在这个项目中通常会被其他组件模块(yudao-spring-boot-starter-xxxx)和业务模块的api模块(yudao-module-xxxxx-api)所引用。
除了yudao-common外其余的都是封装的框架功能模块,模块名格式为yudao-spring-boot-starter-xxxx,分为业务组件和技术组件。技术组件模块名中没有biz,业务组件是有的。业务组件通常会引用业务模块的api模块(yudao-module-xxxxx-api)
例如数据权限yudao-spring-boot-starter-biz-data-permission组件依赖了体系管理业务模块的api:yudao-module-system-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">
<parent>
<artifactId>yudao-framework</artifactId>
<groupId>cn.iocoder.boot</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-spring-boot-starter-biz-data-permission</artifactId>
<packaging>jar</packaging>
......
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
.........
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-system-api</artifactId>
<version>${revision}</version>
</dependency>
.........
</project>
复制代码
该模块下的包名都以cn.iocoder.yudao.framework开头,背面是组件名称,然后再往下大多又分成config和core两个包,config包下是spring-boot的配置类,与组件本身的配置有关,core包下是组件详细功能的实当代码,需要注意的是config包下的配置类会配合resources/META-INF.spring下的org.springframework.boot.autoconfigure.AutoConfiguration.imports文件使用,配置类的类路径只有配在这个文件中,才会被spring扫描到,然后将组件注入spring容器中,供其他业务模块使用。
framework模块之间也可以相互引用,例如yudao-spring-boot-starter-biz-data-permission就依赖了yudao-spring-boot-starter-security,yudao-spring-boot-starter-mybatis和yudao-spring-boot-starter-test
<?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">
<parent>
<artifactId>yudao-framework</artifactId>
<groupId>cn.iocoder.boot</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-spring-boot-starter-biz-data-permission</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>数据权限</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-security</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-mybatis</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-system-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
复制代码
3.4 yudao-module-xxxxx
yudao-module-xxxxx模块是实现详细业务的模块,详细结构如下:
(xxxxx为业务名,aaa,bbb为业务下的详细功能名)
yudao-module-xxxxx
│
│── yudao-module-xxxxx-api
│ ├─ src
│ │ └─ main
│ │ └─ java
│ │ └─ cn.iocoder.yudao.module.xxxxx
│ │ ├─ api
│ │ │ ├─ aaa
│ │ │ │ ├─ dto
│ │ │ │ │ └─ AaaRespDTO.java
│ │ │ │ └─ AaaApi.java
│ │ │ └─ bbb
│ │ │ ├─ dto
│ │ │ │ └─ BbbRespDTO.java
│ │ │ └─ BbbApi.java
│ │ └─ enums
│ │ ├─ aaa
│ │ │ └─ AaaCccEnum.java
│ │ │ └─ AaaDdddEnum.java
│ │ ├─ bbb
│ │ │ └─ BbbCccEnum.java
│ │ │ └─ BbbDdddEnum.java
│ │ │
│ │ ├─ AaaTypeConstants.java
│ │ └─ BbbTypeConstants.java
│ │
│ └─ pom.xml
│
│── yudao-module-xxxxx-biz
│ ├─ src
│ │ └─ main
│ │ ├─ java
│ │ | └─ cn.iocoder.yudao.module.xxxxx
│ │ | ├─ api
│ │ | │ ├─ aaa
│ │ | │ │ └─ AaaApiImpl.java
│ │ | │ └─ bbb
│ │ | │ └─ BbbApiImpl.java
│ │ | │
│ │ | ├─ controller
│ │ | │ ├─ admin
│ │ | │ │ ├─ aaa
│ │ | │ │ │ ├─ vo
│ │ | │ │ │ │ └─ AaaReqVO.java
│ │ | │ │ │ └─ AaaController.java
│ │ | │ │ └─ bbb
│ │ | │ │ ├─ vo
│ │ | │ │ │ └─ BbbReqVO.java
│ │ | │ │ └─ BbbController.java
│ │ | │ │
│ │ | │ └─ app
│ │ | │ └─ aaa
│ │ | │ ├─ vo
│ │ | │ │ └─ AaaAppReqVO.java
│ │ | │ └─ AaaAppController.java
│ │ | │
│ │ | ├─ convert
│ │ | │ ├─ aaa
│ │ | │ │ └─ AaaConvert.java
│ │ | │ └─ bbb
│ │ | │ └─ BbbConvert.java
│ │ | │
│ │ | ├─ framework
│ │ | ├─ job
│ │ | ├─ mq
│ │ | ├─ service
│ │ | │ ├─ aaa
│ │ | │ │ └─ AaaService.java
│ │ | │ │ └─ AaaServiceImpl.java
│ │ | │ └─ bbb
│ │ | │ └─ BbbService.java
│ │ | │ └─ BbbServiceImpl.java
│ │ | │
│ │ | │
│ │ | └─ dal
│ │ | ├─ dataobject
│ │ | │ ├─ aaa
│ │ | │ │ └─ AaaDO.java
│ │ | │ └─ bbb
│ │ | │ └─ BbbDO.java
│ │ | └─ mysql
│ │ | ├─ aaa
│ │ | │ └─ AaaMapper.java
│ │ | └─ bbb
│ │ | └─ BbbMapper.java
│ │ │
│ │ └─ resource
│ │ └─ mapper
│ │ ├─ aaa
│ │ │ └─ AaaMapper.xml
│ │ └─ bbb
│ │ └─ BbbMapper.xml
│ └── pom.xml
│
└── pom.xml
复制代码
整个项目的Controller, Service, Mapper都封装在业务模块里,业务模块是根据详细的业务来建立的。
每个业务模块都由yudao-module-xxxxx-api和yudao-module-xxxxx-biz两个子模块组成。yudao-module-xxxxx-api模块中是开放给其他业务模块或业务组件调用的接口代码和一些公共的枚举和常量,yudao-module-xxxxx-biz模块中是详细业务的实当代码,因为api定义的接口是biz实现的,因此biz模块起首要依赖它自己要实现的api模块。
模块内包名都是固定前缀cn.iocoder.yudao加module再加业务模块名的情势,例如:cn.iocoder.yudao.module.xxxxx,在此基础上根据
所属层级
建立下一级包名,例如cn.iocoder.yudao.module.xxxxx.controller.admin,cn.iocoder.yudao.module.xxxxx.service,然后根据
详细业务功能
再建立更深层级的包名和包下的类,例如:cn.iocoder.yudao.module.xxxxx.controller.admin.aaa.vo。
包名解释:
yudao-module-xxxxx-api
cn.iocoder.yudao.module.xxxxx.api
包存放业务模块需要对外暴漏的接口,以及用于传输数据的DTO对象。
cn.iocoder.yudao.module.xxxxx.enums
包存放该业务模块的枚举类和常量类,既供自己使用,也供调用方使用。
yudao-module-xxxxx-biz
cn.iocoder.yudao.module.xxxxx.api
包存放对api模块定义的接口类的实现(***ApiImpl),实现类为Spring容器管理,被Spring注入到调用者引用的Api接口上,ApiImpl和Controller一样,接收到调用后再调用业务层Service代码。
cn.iocoder.yudao.module.xxxxx.controller
分为admin和app两个子包,分别放置管理员接口和会员接口,包中存放Controller类及接收和天生JSON的实体类VO,接收http请求并返回数据。
cn.iocoder.yudao.module.xxxxx.service
包下是详细的Service业务接口和实现类。
cn.iocoder.yudao.module.xxxxx.dal
包是负责数据库访问的DAO层,分为dataobject和mysql两个包,dataobject包内存放的是DO对象,mysql包内存放的是Mybatis/Mybatis-Plus的Mapper类,Java代码无法实现的复杂SQL,可在resources文件夹内定义"*Mapper.xml"文件实现。
cn.iocoder.yudao.module.xxxxx.convert
包功能比较简单,用于存放mapstruct转换器类,用于各种不同类型的实体类对象之间的深拷贝互相转换。
cn.iocoder.yudao.module.xxxxx.mq
消息发送接收。
cn.iocoder.yudao.module.xxxxx.job
定时任务。
cn.iocoder.yudao.module.xxxxx.framework
配合yudao-framework模块封装的框架和功能来实现一些更高级的功能,例如文档天生,数据权限等等。
......
业务模块biz之间是相互独立的
,如biz模块间要相互调用,只要互相引用对方的api模块坐标到自己biz的pom.xml即可,这样的模块依赖方式完美遵循
依赖倒置原则
,如果是biz直接引用biz不但违背依赖倒置原则,而且可能还会导致maven构建时报出循环引用的错误。本项目中后续还会出现业务组件框架模块(yudao-spring-boot-starter-biz-xxxxxxxx)依赖详细业务模块的情况,同样也是需要引用业务模块的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">
<parent>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-system</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-system-biz</artifactId>
<packaging>jar</packaging>
... ...
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-system-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-infra-api</artifactId>
<version>${revision}</version>
</dependency>
... ...
</project>
复制代码
3.5 yudao-server
yudao-server是启动项目的模块,内里有spring-boot主启动类cn.iocoder.yudao.server.YudaoServerApplication,缺省的请求处置惩罚类cn.iocoder.yudao.server.controller.DefaultController,不同环境的配置文件application-*.yml,还有一个logback的日志配置文件logback-spring.xml。
yudao-server
|
├─ src
| └─ main
| ├─ java
| | └─ cn.iocoder.yudao.server
| | └─ controller
| | └─ DefaultController.java
| | └─ YudaoServerApplication.java
| |
| └─ resources
| └─ application.yaml
| └─ application-dev.yaml
| └─ application-local.yaml
| └─ logback-spring.xml
|
└─ pox.xml
复制代码
yudao-server模块汇聚了所有的业务模块,打包上线的可执行jar包就是这个模块编译而成的,该模块聚合了所有的业务模块的biz模块(yudao-module-***-biz)以及一些需要直接引用的starter,需要启用哪个业务模块就可以按需引入哪个业务模块。
/yudao-server/pom.xml中,引入了项目最核心的两个业务模块:体系管理yudao-module-system-biz和服务保障yudao-module-infra-biz,默认不引入其他业务模块从而加快编译速率,还引入了一些其他的starter,最后通过spring-boot-maven-plugin插件将此模块代码打包为可执行的jar包,从而启动整个项目。
<?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">
<parent>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-server</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
后端 Server 的主项目,通过引入需要 yudao-module-xxx 的依赖,
从而实现提供 RESTful API 给 yudao-ui-admin、yudao-ui-user 等前端项目。
本质上来说,它就是个空壳(容器)!
</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-system-biz</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-infra-biz</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-protection</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
复制代码
cn.iocoder.yudao.server.YudaoServerApplication是整个项目的主启动类,通过注解@SpringBootApplication(scanBasePackages = {"${yudao.info.base-package}.server", "${yudao.info.base-package}.module"})将cn.iocoder.yudao.module下的包列入Spring扫描范围,用于实例化module模块中的类,并纳入Spring容器管理,这也是业务模块(yudao-module-xxx-xxx)下的子包和类必须放在cn.iocoder.yudao.module包下的原因。
package cn.iocoder.yudao.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 项目的启动类
* @author 芋道源码
*/
@SuppressWarnings("SpringComponentScan") // 忽略 IDEA 无法识别 ${yudao.info.base-package}
@SpringBootApplication(scanBasePackages = {"${yudao.info.base-package}.server", "${yudao.info.base-package}.module"})
public class YudaoServerApplication {
public static void main(String[] args) {
SpringApplication.run(YudaoServerApplication.class, args);
}
}
复制代码
controller包下定义了一个缺省的cn.iocoder.yudao.server.controller.DefaultController类,如果被调用的接口所在的模块没有被yudao-server引入,就会被这个类中带着路径通配符的接口方法“兜底”,给出对应的错误提示,这个也是芋道源码中比较精巧的筹划之一。
package cn.iocoder.yudao.server.controller;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.NOT_IMPLEMENTED;
/**
* 默认 Controller,解决部分 module 未开启时的 404 提示。
* 例如说,/bpm/** 路径,工作流
*
* @author 芋道源码
*/
@RestController
public class DefaultController {
@RequestMapping("/admin-api/bpm/**")
public CommonResult<Boolean> bpm404() {
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
"[工作流模块 yudao-module-bpm - 已禁用][参考 https://doc.iocoder.cn/bpm/ 开启]");
}
@RequestMapping("/admin-api/mp/**")
public CommonResult<Boolean> mp404() {
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
"[微信公众号 yudao-module-mp - 已禁用][参考 https://doc.iocoder.cn/mp/build/ 开启]");
}
@RequestMapping(value = {"/admin-api/product/**", // 商品中心
"/admin-api/trade/**", // 交易中心
"/admin-api/promotion/**"}) // 营销中心
public CommonResult<Boolean> mall404() {
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
"[商城系统 yudao-module-mall - 已禁用][参考 https://doc.iocoder.cn/mall/build/ 开启]");
}
@RequestMapping("/admin-api/erp/**")
public CommonResult<Boolean> erp404() {
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
"[ERP 模块 yudao-module-erp - 已禁用][参考 https://doc.iocoder.cn/erp/build/ 开启]");
}
@RequestMapping("/admin-api/crm/**")
public CommonResult<Boolean> crm404() {
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
"[CRM 模块 yudao-module-crm - 已禁用][参考 https://doc.iocoder.cn/crm/build/ 开启]");
}
@RequestMapping(value = {"/admin-api/report/**"})
public CommonResult<Boolean> report404() {
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
"[报表模块 yudao-module-report - 已禁用][参考 https://doc.iocoder.cn/report/ 开启]");
}
@RequestMapping(value = {"/admin-api/pay/**"})
public CommonResult<Boolean> pay404() {
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
"[支付模块 yudao-module-pay - 已禁用][参考 https://doc.iocoder.cn/pay/build/ 开启]");
}
@RequestMapping(value = {"/admin-api/ai/**"})
public CommonResult<Boolean> ai404() {
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
"[AI 大模型 yudao-module-ai - 已禁用][参考 https://doc.iocoder.cn/ai/build/ 开启]");
}
@RequestMapping(value = {"/admin-api/iot/**"})
public CommonResult<Boolean> iot404() {
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
"[IOT 物联网 yudao-module-iot - 已禁用][参考 https://doc.iocoder.cn/iot/build/ 开启]");
}
}
复制代码
3.6 关系图
1.引用关系,箭头由被引用模块指向引用模块
2.继承关系,箭头由父级指向子级
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/)
Powered by Discuz! X3.4