迁移到 Spring Boot 3.0 和 Spring Integration 6.0 后打印警告

Mor*_*bet 13 spring spring-integration spring-boot

将项目从 Spring Boot v2.7 迁移到 v3.0(从而从 Spring Integration v5.5 迁移到 v6.0)后,会打印出以下警告:

\n
WARN 22084 --- [  restartedMain] ocalVariableTableParameterNameDiscoverer : Using deprecated \'-debug\' fallback for parameter name resolution. Compile the affected code with \'-parameters\' instead or avoid its introspection: com.foobar.MyClassA\nWARN 22084 --- [  restartedMain] ocalVariableTableParameterNameDiscoverer : Using deprecated \'-debug\' fallback for parameter name resolution. Compile the affected code with \'-parameters\' instead or avoid its introspection: com.foobar.MyClassB\nWARN 22084 --- [  restartedMain] ocalVariableTableParameterNameDiscoverer : Using deprecated \'-debug\' fallback for parameter name resolution. Compile the affected code with \'-parameters\' instead or avoid its introspection: com.foobar.MyClassC\nWARN 22084 --- [  restartedMain] ocalVariableTableParameterNameDiscoverer : Using deprecated \'-debug\' fallback for parameter name resolution. Compile the affected code with \'-parameters\' instead or avoid its introspection: com.foobar.MyClassD\n
Run Code Online (Sandbox Code Playgroud)\n

MyClassA扩展IntegrationFlowAdapter,并注释为@Component

\n
WARN 22084 --- [  restartedMain] ocalVariableTableParameterNameDiscoverer : Using deprecated \'-debug\' fallback for parameter name resolution. Compile the affected code with \'-parameters\' instead or avoid its introspection: com.foobar.MyClassA\nWARN 22084 --- [  restartedMain] ocalVariableTableParameterNameDiscoverer : Using deprecated \'-debug\' fallback for parameter name resolution. Compile the affected code with \'-parameters\' instead or avoid its introspection: com.foobar.MyClassB\nWARN 22084 --- [  restartedMain] ocalVariableTableParameterNameDiscoverer : Using deprecated \'-debug\' fallback for parameter name resolution. Compile the affected code with \'-parameters\' instead or avoid its introspection: com.foobar.MyClassC\nWARN 22084 --- [  restartedMain] ocalVariableTableParameterNameDiscoverer : Using deprecated \'-debug\' fallback for parameter name resolution. Compile the affected code with \'-parameters\' instead or avoid its introspection: com.foobar.MyClassD\n
Run Code Online (Sandbox Code Playgroud)\n

MyClassB注释为@ConfigurationProperties

\n
package com.foobar;\n\n@Component\nclass MyClassA extends IntegrationFlowAdapter {\n  // \xe2\x80\xa6\n}\n
Run Code Online (Sandbox Code Playgroud)\n

MyClassC注释为@Configuration

\n
package com.foobar;\n\n@ConfigurationProperties("my-config")\nclass MyClassB {\n  // \xe2\x80\xa6\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这个特定的甚至没有扩展任何东西,也没有注释:

\n
package com.foobar;\n\n@Configuration\nclass MyClassC {\n  // \xe2\x80\xa6\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我没有在Spring BootSpring Integration迁移指南中看到任何相关信息。Spring Boot迁移指南中有关于名称解析的章节,但是与Gradle相关,并且使用Maven的I\xe2\x80\x99m。我\xe2\x80\x99m 甚至不确定这个名称解析是关于什么的。

\n

我\xe2\x80\x99m 对类感到困惑LocalVariableTableParameterNameDiscoverer,并且我\xe2\x80\x99m 不确定我\xe2\x80\x99m 应该执行什么迁移任务。

\n

Mor*_*bet 11

正如@m-deinum在问题\xe2\x80\x99s评论中指出的那样,问题与Spring Boot或Spring Integration无关,而是与Spring Framework本身有关。我需要将-parameters选项添加到javac.

\n

如果您使用 Maven,在 中添加以下内容pom.xml应该可以解决问题:

\n
<project>\n  \n  <!-- \xe2\x80\xa6 -->\n\n  <build>\n    <pluginManagement>\n      <plugins>\n        <plugin>\n          <artifactId>maven-compiler-plugin</artifactId>\n          <version>3.11.0</version>\n          <configuration>\n            <parameters>true</parameters>\n          </configuration>\n        </plugin>\n      </plugins>\n    </pluginManagement>\n  </build>\n\n  <!-- \xe2\x80\xa6 -->\n\n</project>\n
Run Code Online (Sandbox Code Playgroud)\n


nyg*_*nyg 10

摩根的答案提供了正确的解决方案,但我想展示一些代码来解释为什么会发生这种情况。

给定以下@Configuration类:

@Configuration
public class AppConfig {

    @Bean
    public SomeBean someBean(FooBar foo, FooBar bar) {
        return new SomeBean(foo, bar);
    }

    @Bean
    public FooBar foo() {
        return new FooBar();
    }

    @Bean
    public FooBar bar() {
        return new FooBar();
    }
}
Run Code Online (Sandbox Code Playgroud)

创建 bean 时someBean,Spring 必须知道该方法的两个参数分别使用哪些 bean someBean()。它通过查看方法的参数名称(即foobar)并将其与现有 bean 的名称进行比较来完成此操作。已弃用的LocalVariableTableParameterNameDiscoverer用于解析方法的参数名称。

-debug但是,如果将标志传递给编译器,则仅在 Java 类编译后才保留参数名称javac。默认情况下,Maven 编译器插件会将此标志传递给 javac。这就是为什么LocalVariableTableParameterNameDiscoverer可以完成它的工作以及发出警告的原因。

通过上面的代码,可以尝试更改 Maven 编译器插件的配置,以不将调试标志传递给 javac:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven-compiler-plugin.version}</version>
            <configuration>
                <debug>false</debug>
            </configuration>
        </plugin>
    </plugins>
</build>
Run Code Online (Sandbox Code Playgroud)

编译并执行应用程序后,警告将被错误替换:

引起:org.springframework.beans.factory.NoUniqueBeanDefinitionException:没有类型为“edu.self.nyg.example.app.FooBar”的合格 bean 可用:期望单个匹配 bean 但找到 2:foo,bar

为了在编译后保留参数名称而不使用调试标志,-parameters必须使用该标志。这将允许 Spring 的StandardReflectionParameterNameDiscoverer替换LocalVariableTableParameterNameDiscoverer并正确找到 的 foo 和 bar 参数的正确 bean someBean()

似乎建议使用-parameters,但要消除警告,如果需要,还可以执行以下操作:

@Bean
public SomeBean someBean(
        @Qualifier("foo") FooBar foo,
        @Qualifier("bar") FooBar bar) {
    return new SomeBean(foo, bar);
}
Run Code Online (Sandbox Code Playgroud)

请注意,将调试和参数标志都设置为 true 是可以的,Spring 将使用StandardReflectionParameterNameDiscoverer并且不会发出警告。

  • 这是一个更完整的答案!TBH,我只是应用了 Spring 框架在日志中告诉我的内容,而不了解发生了什么。我什至对自己的答案并不完全满意,这就是我不接受它的原因。我会接受你的。谢谢! (2认同)