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

    复制代码
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
            <compilerArgs>
                <arg>-parameters</arg>
            </compilerArgs>
        </configuration>
    </plugin>

    如果没有这个插件,就添加它。

  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 {
    // ...
}
```
  1. 重新编译项目。

如果问题仍然存在,可能是因为你的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

复制代码
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.11.0</version>
            <configuration>
                <source>17</source>
                <target>17</target>
                <parameters>true</parameters>  <!-- 关键配置 -->
                <compilerArgs>
                    <arg>-parameters</arg>
                </compilerArgs>
            </configuration>
        </plugin>
    </plugins>
</build>

方案3:在IDEA中配置编译器参数

  1. 打开 File → Settings → Build, Execution, Deployment → Compiler → Java Compiler

  2. 在"Additional command line parameters"中添加:-parameters

  3. 点击OK并重新构建项目

方案4:临时禁用Actuator(如果不需要)

application.ymlapplication.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依赖
    <!--
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    -->
    # 然后重新clean和编译
  3. 清理并重新构建

    bash

    复制代码
    mvn clean compile -DskipTests

验证修复:

修复后,启动日志应该显示正常,不会再有Bean冲突的错误。应用应该能够成功启动到类似这样的日志:

text

复制代码
Started RuoYiApplication in XX.XXX seconds

为什么之前可以启动?

可能是因为之前的编译产物中保留了某些参数信息,或者IDE缓存了编译结果。clean之后,所有编译产物被清除,重新编译时没有使用-parameters参数,导致Spring无法正确区分两个Bean。

请先尝试方案1(添加@Qualifier注解),这通常是最有效的解决方案。如果问题仍然存在,请告诉我具体的SecurityConfig类代码,我可以提供更精确的修复建议。

相关推荐
吴声子夜歌几秒前
MongoDB 4.x——微服务入门
java·mongodb·微服务
Yana.nice10 分钟前
Linux logrotate 日志切割未生效
linux·运维·服务器
好好沉淀15 分钟前
主键选择(自增 vs UUID vs 雪花算法)
java·算法
一叶龙洲25 分钟前
ubuntu26.04 xfce美化成mac
服务器·ubuntu·macos
Увидимся вчера28 分钟前
绿盟堡垒机自动化任务—自动改密失败
linux·服务器·自动化
带刺的坐椅28 分钟前
Solon AI:Tool 与 Talent 怎么选?从函数到领域专家
java·ai·llm·agent·solon
小白说大模型1 小时前
AI Agent 调试实战:链路追踪、Prompt 可视化与异常定位的系统方法
java·人工智能·python·算法·prompt
静水楼台x1 小时前
spring security
java·数据库·spring
重生之我是Java开发战士1 小时前
【Java EE】Spring Boot配置文件
java·spring boot·java-ee
Tim_101 小时前
【C++】019、内存泄漏
java·开发语言