
欢迎来到预见猿份,本站项目均为站长原创,学习中有问题可直接提交给站长老苗解决(微信:mrt_0607)。
苗润土老师,20余年一线项目经验,2014年加入黑马,星辰wms、云岚到家、学成在线项目作者,历任高级讲师、教学主管及课程研究员。 b站老苗
Q&A
数据字典不显示
首先确保数据字典配置完成,前端代码中引入数据字典的地方都正确。
然后清除 redis 缓存,删除 dict 下的全部内容。

最后退出系统,再次登录。
Mybatis-Plus 没有输出 sql
修改 application-dev.yml,按下图配置:

循环依赖
什么是循环依赖
在 Spring 中,如果一个 bean 尝试将自身引用注入到自身中,通常会引发循环依赖。
首先搞清楚什么是循环依赖:
两个 Bean,A 依赖 B,B 依赖 A 就构成了循环依赖,如下图:

同样的道理,如果在 A 中注入 A 表示 A 依赖 A,也就构成了循环依赖。
Spring 如何解决循环依赖
以上图为例说明 Spring 是如何处理循环依赖问题的?
首先按照常规的流程是:
创建 A 实例 → 初始化 A → 注入 B → 创建 B 实例 → 初始化 B → 注入 A
在初始化 A 时需要注入 B,要注入 B 就需要创建 B 实例再初始化 B,而在初始化 B 时需要注入 A,此时 A 还没有创建完成就陷入死循环。
针对循环依赖的问题 Spring 把上边的过程调整为下边的流程:
创建 A 实例 → 创建 B 实例 → 在 B 中注入 A → B 初始化 → 在 A 中注入 B → A 初始化。
Spring 是如何做到呢?
Spring 会延迟初始化,B 需要注入 A,此时 Spring 会先实例化 A,把一个半成品 A 注入给 B,延迟 A 的初始化。
具体的底层原理是 Spring 通过三级缓存实现:
- singletonObjects 缓存:这是 Spring 容器用来缓存完全初始化好的单例 bean 实例的缓存。当一个 bean 初始化完成后,它会被放入 singletonObjects 缓存中。这个缓存是单例 bean 的最终缓存,也是 BeanFactory 中保存 bean 的主要缓存。
- earlySingletonObjects 缓存:这个缓存是用来保存被实例化但还未完全初始化的 bean 的引用。当一个 bean 已经被实例化(但还未初始化)时,它会被放入 earlySingletonObjects 缓存中。
- singletonFactories 缓存:这个缓存保存的是用于创建 bean 实例的 ObjectFactory,用于支持循环依赖的延迟初始化。当一个 bean 被实例化,但尚未完全初始化时,Spring 会在 singletonFactories 缓存中查找该 bean 的 ObjectFactory。这个 ObjectFactory 会在需要时被调用来完成 bean 的初始化。
Spring 通过这三级缓存的组合,来确保在循环依赖情况下,能够正常初始化 bean。当两个或多个 bean 之间存在循环依赖时,Spring 使用 singletonFactories 缓存来存储 bean 的提供者(ObjectFactory)。当一个 bean 在初始化过程中需要依赖另一个还未初始化的 bean 时,Spring 会调用相应的 ObjectFactory 来获取对应的 bean 实例,这样就实现了循环依赖的延迟初始化。一旦 bean 初始化完成,它就会被移动到 singletonObjects 缓存中。
举例:
创建 A 实例 → 创建 B 实例 → 在 B 中注入 A → B 初始化 → 在 A 中注入 B → A 初始化。
- 创建 A 实例(半成品),在 earlySingletonObjects 放入 A 半成品。
- 创建 B 实例(半成品),在 earlySingletonObjects 放入 B 半成品。
- 在 B 中注入 A,通过 singletonFactories 拿到 A 的对象工厂,通过对象工厂拿到 A 的半成品注入到 B 中。
- B 初始化完成,将 B 从 earlySingletonObjects 移动到 singletonObjects。
- A 初始化完成,将 A 从 earlySingletonObjects 移动到 singletonObjects。
构造参数注入解决循环依赖问题
虽然 Spring 可以解决上边通过成员变量注入引发的循环依赖问题,但是通过构造参数注入引发的循环依赖问题是会报错的。
如下图:

为什么上图中的循环依赖会报错呢?
因为创建 C 需要调用构造方法,而构造方法需要依赖 D,此时 C 是无法实例化的,上边分析 Spring 解决循环依赖是通过延迟初始化,当出现循环依赖问题可以注入一个半成品,而这里连半成品都无法创建成功。
如何解决这种通过构造参数注入导致的循环依赖问题呢?
可以在 C 或 D 的任意一方注入另一方的代理对象而不是注入原始对象,如下:
假设在 C 的构造方法中注入 D 的代理对象可以写为:
在构造参数前加 @Lazy 注解,表示注入 D 的代理对象。
public C(@Lazy D d) {
...
}解决循环依赖配置
异常信息:The dependencies of some of the beans in the application context form a cycle:
解决:
在 spring boot 配置文件中添加:
spring:
main:
allow-circular-references: true找到多个 bean
Field service in org.jeecg.common.system.base.controller.JeecgController required a single bean, but 2 were found:
- wmsInventoryTransByAllocation: defined in file [D:\course\wms\course_code\xingchenWMS-java\jeecg-module-wms\target\classes\org\jeecg\modules\wms\inventory\service\impl\WmsInventoryTransByAllocation.class]
- wmsInventoryTransByReceiving: defined in file [D:\course\wms\course_code\xingchenWMS-java\jeecg-module-wms\target\classes\org\jeecg\modules\wms\inventory\service\impl\WmsInventoryTransByReceiving.class]IWmsInventoryTransService 类型的 bean 有多个,如果使用下边的方式注入则会报上边的错误,@Autowired 是基于类型注入,而 IWmsInventoryTransService 类型有多个 bean。
@Autowired
private IWmsInventoryTransService wmsInventoryTransService;正确的方法是注入该接口的具体实现类的 bean。
Ollama 启动端口 11434 被占用问题
Error: listen tcp 127.0.0.1:11434: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.结果:错误是由于 ollama 已经启动而导致。
解决方法:
在系统任务管理器中关闭 ollama 以及 ollama.exe 进程。
再次运行,提示正常。
Knife4j 文档展示异常
当不同的接口方法 operationId 是相同的,在展示接口时只会展示一个。
比如下边的方法:

如果在 operation 注解中不设置 operationId,则 operationId 的值为方法名,如果工程中有多个 queryPageList 的方法,则 operationId 相同,最终展示接口时只会展示一个 queryPageList。
所以我们应该设置 operationId,整个工程中的 operationId 是唯一的。

Windows 端口占用
假如是 11434 端口占用,先查询 11434 端口是哪个进程占用了。
C:\Users\mrt>netstat -ano | findstr :11434
TCP 127.0.0.1:11434 0.0.0.0:0 LISTENING 34644然后再杀死占用端口的进程
C:\Users\mrt>taskkill /PID 34644
成功: 给进程发送了终止信号,进程的 PID 为 34644。Cron 表达式
Cron 表达式是一个字符串,通过它可以定义调度策略,格式如下:
{秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)}Cron 的各个域的定义如下表格所示:

一些例子如下:
0 0 0 * * ?每天 0 点触发30 10 1 * * ?每天 1 点 10 分 30 秒触发0/30 * * * * ?每 30 秒触发一次* 0/10 * * * ?每 10 分钟触发一次
为了方便测试这里第 5 秒执行一次,设置为:0/5 * * * * ?
cron 表达式的难点在于通配符,下边的内容请自行阅读:
,这里指的是在两个以上的时间点中都执行,如果我们在“分”这个域中定义为8,12,35,则表示分别在第 8 分、第 12 分、第 35 分执行该定时任务。-这个比较好理解,就是指定在某个域的连续范围,如果我们在“时”这个域中定义1-6,则表示在 1 到 6 点之间每小时都触发一次,用,表示1,2,3,4,5,6。*表示所有值,可解读为“每”。如果在“日”这个域中设置*,表示每一天都会触发。?表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的 8 号触发一个操作,但不关心是周几,我们可以这么设置0 0 0 8 * ?。/在某个域上周期性触发,该符号将其所在域中的表达式分为两个部分,其中第一部分是起始值,除了秒以外都会降低一个单位,比如在“秒”上定义5/10表示从第 5 秒开始每 10 秒执行一次,而在“分”上则表示从第 5 分钟开始每 10 分钟执行一次。L表示英文中的 LAST 的意思,只能在“日”和“周”中使用。在“日”中设置,表示当月的最后一天(依据当前月份,如果是二月还会依据是否是闰年),在“周”上表示周六,相当于 “7” 或 “SAT”。如果在 “L” 前加上数字,则表示该数据的最后一个。例如在“周”上设置 “7L” 这样的格式,则表示“本月最后一个周六”。W表示离指定日期的最近那个工作日(周一至周五)触发,只能在“日”中使用且只能用在具体的数字之后。若在“日”上置 “15W”,表示离每月 15 号最近的那个工作日触发。假如 15 号正好是周六,则找最近的周五(14 号)触发;如果 15 号是周末,则找最近的下周一(16 号)触发;如果 15 号正好在工作日(周一至周五),则就在该天触发。如果是 “1W” 就只能往本月的下一个最近的工作日推,不能跨月往上一个月推。#表示每月的第几个周几,只能作用于“周”上。例如 “2#3” 表示在每月的第三个周二。
unable to create database 'mydb'
ERROR io.micrometer.influx.InfluxMeterRegistry:116 - unable to create database 'mydb'产生原因:
- 依赖存在:项目中引入了
micrometer-registry-influx依赖。 - 自动配置:Spring Boot 的自动配置机制检测到这个依赖后,会自动尝试配置一个
InfluxMeterRegistry,以便将应用的监控指标(如 JVM 内存、CPU、HTTP 请求等)推送到 InfluxDB。 - 配置缺失/错误:自动配置尝试使用默认连接参数(如数据库名
mydb、URLhttp://localhost:8086,以及空 token/密码)去连接 InfluxDB。 - 认证失败:使用的 InfluxDB 2.x 版本需要基于 Token 的认证,而客户端要么没有提供 Token,要么提供了错误的 Token,导致连接和创建数据库失败,从而在日志中报错。
解决:
彻底禁用 InfluxDB 指标导出。
在 application-dev.yml 中配置如下:
management:
influx:
metrics:
export:
enabled: false效果如下:

IDEA 不自动编译
启动脚本中添加 Add before launch task

点击下图的加号,添加 Build Project

IDEA 中一直 indexing 问题
Idea 打开 vue 工程会很卡,一直提示 indexing 中。
在 setting 中设置忽略的文件目录或文件类型。
前端工程的依赖在 node_modules 中,我们设置忽略此目录的索引:

