SpringBoot3.x与Actuator冲突解决方案

复制代码
自己手痒随便点了一下debug时候的一个推荐安装,自动引入了这个依赖,后边重新clean后打包部署的时候就报错

也算是以来冲突报错。

在Spring Boot 3.x中,如果你同时使用了Spring MVC和Actuator,并且Actuator的端点是通过MVC暴露的(即使用了spring-boot-starter-actuator),那么会自动配置两个HandlerMapping

  1. requestMappingHandlerMapping:用于常规的MVC控制器。

  2. controllerEndpointHandlerMapping:用于Actuator的端点。

SecurityConfig中,你注入了一个RequestMappingHandlerMapping,但是因为存在两个候选Bean,Spring不知道注入哪一个,所以报错。

复制代码
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-actuator</artifactId>-->
<!--        </dependency>-->

启动报错信息如下

report,40\] - \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* APPLICATION FAILED TO START \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Description: Field permitAllUrl in com.hgwy.notification.framework.config.SecurityConfig required a single bean, but 2 were found: - requestMappingHandlerMapping: defined by method 'requestMappingHandlerMapping' in class path resource \[org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class\] - controllerEndpointHandlerMapping: defined by method 'controllerEndpointHandlerMapping' in class path resource \[org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.class\] This may be due to missing parameter name information Action: Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed Ensure that your compiler is configured to use the '-parameters' flag. You may need to update both your build tool settings as well as your IDE. (See https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x#parameter-name-retention) Disconnected from the target VM, address: '127.0.0.1:12154', transport: 'socket' Process finished with exit code 1 自己解决:解决吧插件的依赖在maven中注释掉 ai解决: 根据错误信息,问题在于Spring Boot 3.x 和 Actuator 的兼容性,以及Spring Security配置中注入了`RequestMappingHandlerMapping`,但是存在两个同类型的Bean(一个来自Spring MVC,一个来自Actuator)。 在Spring Boot 3.x中,如果你同时使用了Spring MVC和Actuator,并且Actuator的端点是通过MVC暴露的(即使用了`spring-boot-starter-actuator`),那么会自动配置两个`HandlerMapping`: 1. `requestMappingHandlerMapping`:用于常规的MVC控制器。 2. `controllerEndpointHandlerMapping`:用于Actuator的端点。 在`SecurityConfig`中,你注入了一个`RequestMappingHandlerMapping`,但是因为存在两个候选Bean,Spring不知道注入哪一个,所以报错。 解决方案: 1. 使用`@Qualifier`指定注入的Bean名称(例如,注入名为`requestMappingHandlerMapping`的Bean)。 2. 或者,如果你不需要Actuator的端点,可以排除Actuator的自动配置。 但是,根据你的描述,在clean之前可以启动,clean之后不能启动,这可能是由于clean之后重新编译,而编译时没有使用`-parameters`参数,导致参数名信息丢失,进而导致`@Qualifier`注解(如果已经使用)没有正确生效。 因此,我们需要做两件事情: 1. 确保在编译时使用了`-parameters`参数(这样Spring在注入时可以通过参数名来区分Bean)。 2. 在代码中使用`@Qualifier`明确指定要注入的Bean。 步骤: 第一步:在pom.xml中配置编译器插件,确保使用`-parameters`参数。 第二步:修改`SecurityConfig`类,在注入`RequestMappingHandlerMapping`的地方添加`@Qualifier("requestMappingHandlerMapping")`。 具体操作: 1. 在pom.xml中,找到maven-compiler-plugin插件,添加配置: xml ``` org.apache.maven.plugins maven-compiler-plugin 3.8.1 -parameters ``` 如果没有这个插件,就添加它。 2. 在`SecurityConfig`类中,找到注入`RequestMappingHandlerMapping`的地方,修改为: java ``` @Autowired @Qualifier("requestMappingHandlerMapping") private RequestMappingHandlerMapping requestMappingHandlerMapping; ``` 但是,如果你在`SecurityConfig`中并没有直接使用`RequestMappingHandlerMapping`,而是通过方法参数注入,那么你可能需要检查你的配置方法。例如,如果你有这样一个方法: text ```` ```java @Bean public SecurityFilterChain filterChain(HttpSecurity http, RequestMappingHandlerMapping mapping) throws Exception { // ... } ``` ```` 那么你需要在这个方法参数上添加`@Qualifier`: text ```` ```java @Bean public SecurityFilterChain filterChain(HttpSecurity http, @Qualifier("requestMappingHandlerMapping") RequestMappingHandlerMapping mapping) throws Exception { // ... } ``` ```` 3. 重新编译项目。 如果问题仍然存在,可能是因为你的IDE(IntelliJ IDEA)没有使用`-parameters`参数进行编译。你可以在IDEA中设置: text ``` File -> Settings -> Build, Execution, Deployment -> Compiler -> Java Compiler -> Additional command line parameters: 添加`-parameters` ``` 然后重新构建项目。 另外,如果你不想使用Actuator的MVC端点,可以尝试禁用Actuator的MVC端点,只使用JMX或者其他方式。但是,根据错误信息,你正在使用WebMvc,所以可能需要通过`@Qualifier`来解决。 如果上述方法都不能解决问题,你可以尝试在`SecurityConfig`中排除对`RequestMappingHandlerMapping`的自动注入,而是通过`ApplicationContext`来获取Bean,但这样不太优雅。 但是,根据你的错误信息,我注意到你使用的是Spring Boot 3.3.5,而Actuator是自动配置的。所以,请按照上述步骤操作。 最后,请确保你的Spring Boot版本和所有依赖版本兼容。你使用的是Spring Boot 3.3.5,那么相应的Spring Security版本应该是6.3.4(从你的依赖中可以看出),这应该是兼容的。 希望这能帮助你解决问题。 看到您正在本地使用IntelliJ IDEA运行项目,并且遇到了和服务器上一样的错误。这个问题的根本原因是Spring Boot 3.x与Spring Security配置之间的一个已知兼容性问题。 ### 问题分析: 从日志可以看到,您在本地启动时也遇到了同样的Bean冲突: text ``` Field permitAllUrl in com.hgwy.notification.framework.config.SecurityConfig required a single bean, but 2 were found: - requestMappingHandlerMapping - controllerEndpointHandlerMapping ``` ### 为什么clean之后启动不了? 1. **Maven clean会清理target目录**,重新编译时可能会丢失一些编译信息 2. **Spring Boot 3.x对参数名保留有更高要求** ,需要`-parameters`编译参数 3. **Actuator自动配置冲突** :在Spring Boot 3.x中,Actuator会创建一个额外的`controllerEndpointHandlerMapping` ### 解决方案: #### 方案1:修改SecurityConfig类(最直接) 找到`SecurityConfig.java`文件,在`RequestMappingHandlerMapping`字段上添加`@Qualifier`注解: java ``` import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; @Configuration @EnableWebSecurity public class SecurityConfig { @Autowired @Qualifier("requestMappingHandlerMapping") // 添加这行 private RequestMappingHandlerMapping requestMappingHandlerMapping; // 其他代码... } ``` #### 方案2:修改Maven编译配置 在`pom.xml`中添加编译器参数: xml ``` org.apache.maven.plugins maven-compiler-plugin 3.11.0 17 17 true -parameters ``` #### 方案3:在IDEA中配置编译器参数 1. 打开 **File → Settings → Build, Execution, Deployment → Compiler → Java Compiler** 2. 在"Additional command line parameters"中添加:`-parameters` 3. 点击OK并重新构建项目 #### 方案4:临时禁用Actuator(如果不需要) 在`application.yml`或`application.properties`中: yaml ``` # application.yml management: endpoints: enabled-by-default: false endpoint: health: enabled: true # 只保留health端点 ``` #### 方案5:使用更优雅的注入方式 修改SecurityConfig中的注入方式: java ``` @Configuration @EnableWebSecurity public class SecurityConfig { // 方法1:使用构造器注入 private final RequestMappingHandlerMapping requestMappingHandlerMapping; public SecurityConfig( @Qualifier("requestMappingHandlerMapping") RequestMappingHandlerMapping requestMappingHandlerMapping ) { this.requestMappingHandlerMapping = requestMappingHandlerMapping; } // 方法2:使用setter注入 /* @Autowired @Qualifier("requestMappingHandlerMapping") public void setRequestMappingHandlerMapping(RequestMappingHandlerMapping mapping) { this.requestMappingHandlerMapping = mapping; } */ } ``` ### 快速修复步骤: 1. **立即修复**: bash ``` # 1. 停止当前运行 # 2. 找到SecurityConfig.java,添加@Qualifier注解 # 3. 重新运行 ``` 2. **如果无法立即修改代码**,可以临时排除Actuator: bash ``` # 在pom.xml中临时注释掉actuator依赖 # 然后重新clean和编译 ``` 3. **清理并重新构建**: bash ``` mvn clean compile -DskipTests ``` ### 验证修复: 修复后,启动日志应该显示正常,不会再有Bean冲突的错误。应用应该能够成功启动到类似这样的日志: text ``` Started RuoYiApplication in XX.XXX seconds ``` **为什么之前可以启动?** 可能是因为之前的编译产物中保留了某些参数信息,或者IDE缓存了编译结果。clean之后,所有编译产物被清除,重新编译时没有使用`-parameters`参数,导致Spring无法正确区分两个Bean。 请先尝试**方案1**(添加@Qualifier注解),这通常是最有效的解决方案。如果问题仍然存在,请告诉我具体的SecurityConfig类代码,我可以提供更精确的修复建议。

相关推荐
heartbeat..6 小时前
Redis 中的锁:核心实现、类型与最佳实践
java·数据库·redis·缓存·并发
i建模6 小时前
在 Rocky Linux 上安装轻量级的 XFCE 桌面
linux·运维·服务器
7 小时前
java关于内部类
java·开发语言
好好沉淀7 小时前
Java 项目中的 .idea 与 target 文件夹
java·开发语言·intellij-idea
gusijin7 小时前
解决idea启动报错java: OutOfMemoryError: insufficient memory
java·ide·intellij-idea
To Be Clean Coder7 小时前
【Spring源码】createBean如何寻找构造器(二)——单参数构造器的场景
java·后端·spring
吨~吨~吨~7 小时前
解决 IntelliJ IDEA 运行时“命令行过长”问题:使用 JAR
java·ide·intellij-idea
你才是臭弟弟7 小时前
SpringBoot 集成MinIo(根据上传文件.后缀自动归类)
java·spring boot·后端
短剑重铸之日7 小时前
《设计模式》第二篇:单例模式
java·单例模式·设计模式·懒汉式·恶汉式
码农水水7 小时前
得物Java面试被问:消息队列的死信队列和重试机制
java·开发语言·jvm·数据结构·机器学习·面试·职场和发展