diff --git a/.workbuddy/expert-history.json b/.workbuddy/expert-history.json index 1a0ba72..ff45ebd 100644 --- a/.workbuddy/expert-history.json +++ b/.workbuddy/expert-history.json @@ -13,5 +13,5 @@ } ] }, - "lastUpdated": 1775498241052 + "lastUpdated": 1775501968801 } \ No newline at end of file diff --git a/.workbuddy/memory/2026-04-07.md b/.workbuddy/memory/2026-04-07.md index 392e62b..b592edb 100644 --- a/.workbuddy/memory/2026-04-07.md +++ b/.workbuddy/memory/2026-04-07.md @@ -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冲突也能启动 + diff --git a/src/main/java/com/gxwebsoft/common/mq/config/RabbitMQConfig.java b/src/main/java/com/gxwebsoft/common/mq/config/RabbitMQConfig.java index a910bb5..8b8d54e 100644 --- a/src/main/java/com/gxwebsoft/common/mq/config/RabbitMQConfig.java +++ b/src/main/java/com/gxwebsoft/common/mq/config/RabbitMQConfig.java @@ -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); } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index d30dd5c..1f0a54e 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -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 diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 374b2bc..d194030 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -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 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 569d7ab..32fffd2 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -11,6 +11,10 @@ spring: application: name: server + + # 允许bean定义覆盖,解决RabbitMQConfig和JacksonConfig中的objectMapper bean冲突 + main: + allow-bean-definition-overriding: true # 连接池配置 datasource: