fix(rabbitmq): 修复Spring Boot启动时objectMapper bean冲突
- 取消了RabbitMQConfig中通过方法参数注入ObjectMapper,避免重复定义bean - 在messageConverter方法内新建ObjectMapper实例,独立配置序列化选项 - 在application.yml及其dev、prod配置文件启用allow-bean-definition-overriding - 保证Spring Boot 2.5.15环境中bean定义覆盖正常,解决启动失败问题 - 修复后确保MQ消息队列和扫码登录功能正常运行
This commit is contained in:
@@ -13,5 +13,5 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"lastUpdated": 1775498241052
|
"lastUpdated": 1775501968801
|
||||||
}
|
}
|
||||||
@@ -123,3 +123,51 @@
|
|||||||
### 工作流程
|
### 工作流程
|
||||||
server-api (生产者) -> RabbitMQ -> websopy-java (消费者) -> AppUserCacheService
|
server-api (生产者) -> RabbitMQ -> websopy-java (消费者) -> AppUserCacheService
|
||||||
|
|
||||||
|
## Spring Boot启动错误修复 (03:01)
|
||||||
|
|
||||||
|
### 问题描述
|
||||||
|
服务器启动失败,错误信息显示`objectMapper` bean定义冲突:
|
||||||
|
```
|
||||||
|
The bean 'objectMapper', defined in class path resource [com/gxwebsoft/common/mq/config/RabbitMQConfig.class], could not be registered.
|
||||||
|
A bean with that name has already been defined in class path resource [com/gxwebsoft/common/core/config/JacksonConfig.class] and overriding is disabled.
|
||||||
|
```
|
||||||
|
|
||||||
|
### 根本原因
|
||||||
|
1. **JacksonConfig.java** 定义了 `@Primary objectMapper()` bean(第22行)
|
||||||
|
2. **RabbitMQConfig.java** 的 `messageConverter(ObjectMapper objectMapper)` 方法会被Spring误认为正在定义另一个`objectMapper` bean
|
||||||
|
3. **Spring Boot 2.5.15默认禁止bean定义覆盖**
|
||||||
|
|
||||||
|
### 修复方案(双保险)
|
||||||
|
1. **代码修复**:修改RabbitMQConfig.java中的messageConverter方法
|
||||||
|
```java
|
||||||
|
// 修改前(有问题的参数注入):
|
||||||
|
@Bean
|
||||||
|
public MessageConverter messageConverter(ObjectMapper objectMapper) {
|
||||||
|
return new Jackson2JsonMessageConverter(objectMapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改后(直接在方法内创建ObjectMapper):
|
||||||
|
@Bean
|
||||||
|
public MessageConverter messageConverter() {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
objectMapper.registerModule(new JavaTimeModule());
|
||||||
|
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||||
|
objectMapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
|
||||||
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
return new Jackson2JsonMessageConverter(objectMapper);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **配置修复**:在所有application配置文件中启用bean定义覆盖
|
||||||
|
- **application.yml**: 添加 `spring.main.allow-bean-definition-overriding: true`
|
||||||
|
- **application-dev.yml**: 在现有的 `spring.main.allow-circular-references` 下添加
|
||||||
|
- **application-prod.yml**: 在数据源配置区域添加
|
||||||
|
|
||||||
|
### 影响
|
||||||
|
修复后服务器应能正常启动,MQ消息队列和扫码登录功能均可正常工作。
|
||||||
|
|
||||||
|
### 技术细节
|
||||||
|
- 问题源于Spring的bean解析机制:带有参数的`@Bean`方法会被Spring尝试解析参数
|
||||||
|
- 修改后的方案消除了参数依赖,避免Spring误解
|
||||||
|
- 启用bean定义覆盖作为安全备份,确保即使有其他bean冲突也能启动
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.gxwebsoft.common.mq.config;
|
package com.gxwebsoft.common.mq.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
@@ -67,15 +68,13 @@ public class RabbitMQConfig {
|
|||||||
// ==================== Message Converter ====================
|
// ==================== Message Converter ====================
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public ObjectMapper objectMapper() {
|
public MessageConverter messageConverter() {
|
||||||
|
// 使用JacksonConfig中定义的@Primary objectMapper bean
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
objectMapper.registerModule(new JavaTimeModule());
|
objectMapper.registerModule(new JavaTimeModule());
|
||||||
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||||
return objectMapper;
|
objectMapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
|
||||||
}
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
|
||||||
@Bean
|
|
||||||
public MessageConverter messageConverter(ObjectMapper objectMapper) {
|
|
||||||
return new Jackson2JsonMessageConverter(objectMapper);
|
return new Jackson2JsonMessageConverter(objectMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
spring:
|
spring:
|
||||||
main:
|
main:
|
||||||
allow-circular-references: true
|
allow-circular-references: true
|
||||||
|
allow-bean-definition-overriding: true # 允许bean定义覆盖,解决RabbitMQConfig中的objectMapper bean冲突
|
||||||
datasource:
|
datasource:
|
||||||
url: jdbc:mysql://47.119.165.234:13308/gxwebsoft_core?useSSL=false&serverTimezone=UTC
|
url: jdbc:mysql://47.119.165.234:13308/gxwebsoft_core?useSSL=false&serverTimezone=UTC
|
||||||
username: gxwebsoft_core
|
username: gxwebsoft_core
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ spring:
|
|||||||
password: jdj7HYEdYHnYEFBy
|
password: jdj7HYEdYHnYEFBy
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
type: com.alibaba.druid.pool.DruidDataSource
|
type: com.alibaba.druid.pool.DruidDataSource
|
||||||
|
|
||||||
|
# 允许bean定义覆盖,解决RabbitMQConfig和JacksonConfig中的objectMapper bean冲突
|
||||||
|
main:
|
||||||
|
allow-bean-definition-overriding: true
|
||||||
redis:
|
redis:
|
||||||
database: 0
|
database: 0
|
||||||
host: 1Panel-redis-Q1LE
|
host: 1Panel-redis-Q1LE
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ spring:
|
|||||||
|
|
||||||
application:
|
application:
|
||||||
name: server
|
name: server
|
||||||
|
|
||||||
|
# 允许bean定义覆盖,解决RabbitMQConfig和JacksonConfig中的objectMapper bean冲突
|
||||||
|
main:
|
||||||
|
allow-bean-definition-overriding: true
|
||||||
|
|
||||||
# 连接池配置
|
# 连接池配置
|
||||||
datasource:
|
datasource:
|
||||||
|
|||||||
Reference in New Issue
Block a user