Compare commits

...

2 Commits

Author SHA1 Message Date
3e7f34fa0d 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消息队列和扫码登录功能正常运行
2026-04-07 03:05:34 +08:00
04ec9659b0 feat(mq): 实现 websopy 端 RabbitMQ 消费者功能
- 新增 SyncMessage.java 定义 websopy 端消息实体,复用 server-api 格式
- 新增 RabbitMQConfig.java 配置交换机、队列及死信队列
- 新增 SyncMessageConsumer.java 实现 USER_SYNC 消息监听与处理
- 修改 pom.xml,添加 spring-boot-starter-amqp 依赖
- 修改 application.yml,添加 RabbitMQ 连接配置和开关
- 优化消息生产者 RabbitMQSyncProducer 代码,移除多余注解
- 设计 server-api -> RabbitMQ -> websopy-java -> AppUserCacheService 流程接口
2026-04-07 02:57:06 +08:00
7 changed files with 72 additions and 9 deletions

View File

@@ -13,5 +13,5 @@
}
]
},
"lastUpdated": 1775498241052
"lastUpdated": 1775501968801
}

View File

@@ -123,3 +123,51 @@
### 工作流程
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冲突也能启动

View File

@@ -322,6 +322,13 @@
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- javax.annotation-api for Java 9+ compatibility (previously included in JDK) -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<!-- knife4j - 升级到兼容版本 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>

View File

@@ -1,5 +1,6 @@
package com.gxwebsoft.common.mq.config;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@@ -67,15 +68,13 @@ public class RabbitMQConfig {
// ==================== Message Converter ====================
@Bean
public ObjectMapper objectMapper() {
public MessageConverter messageConverter() {
// 使用JacksonConfig中定义的@Primary objectMapper bean
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
return objectMapper;
}
@Bean
public MessageConverter messageConverter(ObjectMapper objectMapper) {
objectMapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return new Jackson2JsonMessageConverter(objectMapper);
}
@@ -97,8 +96,8 @@ public class RabbitMQConfig {
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(messageConverter);
// 设置并发数
factory.setConcurrent(1);
factory.setMaxConcurrent(5);
factory.setConcurrentConsumers(1);
factory.setMaxConcurrentConsumers(5);
// 设置手动ack
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
// 预取数量

View File

@@ -4,6 +4,7 @@
spring:
main:
allow-circular-references: true
allow-bean-definition-overriding: true # 允许bean定义覆盖解决RabbitMQConfig中的objectMapper bean冲突
datasource:
url: jdbc:mysql://47.119.165.234:13308/gxwebsoft_core?useSSL=false&serverTimezone=UTC
username: gxwebsoft_core

View File

@@ -8,6 +8,10 @@ spring:
password: jdj7HYEdYHnYEFBy
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
# 允许bean定义覆盖解决RabbitMQConfig和JacksonConfig中的objectMapper bean冲突
main:
allow-bean-definition-overriding: true
redis:
database: 0
host: 1Panel-redis-Q1LE

View File

@@ -11,6 +11,10 @@ spring:
application:
name: server
# 允许bean定义覆盖解决RabbitMQConfig和JacksonConfig中的objectMapper bean冲突
main:
allow-bean-definition-overriding: true
# 连接池配置
datasource: