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

问题描述 投票:0回答:4

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

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
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.MyClassB
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.MyClassC
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.MyClassD

MyClassA
扩展了
IntegrationFlowAdapter
,并用
@Component
:

进行注释
package com.foobar;

@Component
class MyClassA extends IntegrationFlowAdapter {
  // …
}

MyClassB
注释为
@ConfigurationProperties
:

package com.foobar;

@ConfigurationProperties("my-config")
class MyClassB {
  // …
}

MyClassC
注释为
@Configuration
:

package com.foobar;

@Configuration
class MyClassC {
  // …
}

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

package com.foobar;

class MyClassD {
  // …
}

我在Spring BootSpring Integration迁移指南中没有看到任何相关信息。 Spring Boot迁移指南中有一个关于名称解析部分,但它与Gradle相关,而我使用的是Maven。我什至不确定这个名称解析是关于什么的。

我对课程感到困惑

LocalVariableTableParameterNameDiscoverer
,我不知道我应该做什么迁移任务。

spring spring-boot spring-integration
4个回答
8
投票

正如@m-deinum在问题评论中指出的那样,问题与Spring Boot或Spring Integration无关,而是与Spring Framework本身有关。我需要将 -parameters

 选项添加到 
javac

如果您使用 Maven,在

pom.xml

 中添加以下内容应该可以解决问题:

<project> <!-- … --> <build> <pluginManagement> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <parameters>true</parameters> </configuration> </plugin> </plugins> </pluginManagement> </build> <!-- … --> </project>
    

4
投票
Morgan 的

answer 提供了正确的修复方法,但我想展示一些代码来解释为什么会发生这种情况。

给出以下@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(); } }
创建 bean 

someBean

 时,Spring 必须知道为 
someBean()
 方法的两个参数中的每一个使用哪些 bean。它通过查看方法的参数名称(即 
foo
bar
)并将其与现有 bean 的名称进行比较来实现此目的。已弃用的 
LocalVariableTableParameterNameDiscoverer 用于解析方法的参数名称。

但是,只有在将

-debug

 标志传递给 
javac
 编译器时,参数名称才会在 Java 类编译后保留。默认情况下,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>
编译并执行应用程序后,警告将被错误取代:

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

对于要在编译后保留的参数名称而不使用调试标志,必须使用

-parameters

 标志。这将允许 Spring 的 
StandardReflectionParameterNameDiscoverer 替换 LocalVariableTableParameterNameDiscoverer
 并正确找到 
someBean()
 的 foo 和 bar 参数的正确 bean。

似乎建议使用

-parameters

,但要消除警告,如果需要,还可以执行以下操作:

@Bean public SomeBean someBean( @Qualifier("foo") FooBar foo, @Qualifier("bar") FooBar bar) { return new SomeBean(foo, bar); }
请注意,将调试和参数标志都设置为 true 是可以的,Spring 将使用 

StandardReflectionParameterNameDiscoverer

 并且不会发出警告。


3
投票
显然,这被视为一个错误,将在 Spring Framework 6.0.3 中修复。

看起来核心 bean 工厂在构造函数自动装配算法期间不必要地检索构造函数参数名称,尽管没有指定构造函数参数名称。这是我们将在 6.0.3 中修复的一个错误。 [...] 在 6.0.3 上运行相同的代码时,警告应该会消失。

https://github.com/spring-projects/spring-framework/issues/29612#issuecomment-1333705627


2
投票
这与 Spring Integration 和 Spring Boot 都无关。 Spring 框架本身发生了变化:

https://github.com/spring-projects/spring-framework/issues/29563

是的,Spring Integration 使用

LocalVariableTableParameterNameDiscoverer

 中的 
MessagePublishingInterceptor
 来将方法参数作为 SpEL 中的 
@Publisher
 变量 
PublisherMetadataSource.ARGUMENT_MAP_VARIABLE_NAME
https://docs.spring.io/spring-integration /docs/current/reference/html/message-publishing.html#message-publishing
.
另一个是 EvaluationContext

,如果您没有为该注释提供

@MessagingGateway

 属性,我们会尝试从 
@Header
 方法参数解析标头名称:
https://docs.spring.io/spring-integration /docs/current/reference/html/messaging-endpoints.html#mapping-method-arguments

name

中存在类似的逻辑来解析 POJO 服务方法的标头名称:

https://docs.spring.io/spring-integration/docs/current/reference/html/configuration.html#annotations


因此,我们需要来自 Spring Integration 配置的更多信息来确定您可能需要在方法参数的 MessagingMethodInvokerHelper

注释中添加

name

 属性的位置。
我还看到这个 
@Header

LocalVariableTableParameterNameDiscoverer

 中已被弃用。请针对 Spring Integration 提出 GH 问题,以便我们修复它以支持上述
6.0.1

© www.soinside.com 2019 - 2024. All rights reserved.