gpt4 book ai didi

java - Spring Boot 注解配置的时序问题

转载 作者:行者123 更新时间:2023-11-30 08:09:13 26 4
gpt4 key购买 nike

我们在 Spring Boot 应用程序中的 Bean、存储库和 Controller 的计时方面遇到了一个奇怪的问题。

我们有一个由 Map 支持的 NodeRepository。这个 Map 对象应该是我们使用 @Bean 注释创建的 Map,但似乎 Spring 正在创建自己的 Map 并将其注入(inject)到我们的 NodeRepository 上。这是一个问题,因为 Spring 对我们的键值做出了假设,导致 Map 中的键是错误的。

这是所有需要的代码:

org.xxx.Application

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {

return application.sources(Application.class);
}

@Bean
public Map<String, RemoteNode> getRemoteNodeMap() {

HashMap<String, RemoteNode> remoteNodeMap = new HashMap<>();
remoteNodeMap.put("NODE1", this.getRemoteNode1());
remoteNodeMap.put("NODE2", this.getRemoteNode2());

return remoteNodeMap;
}

@Bean(name = "remoteNode1")
public RemoteNode getRemoteNode1() {

return new DefaultRemoteNode("NODE1");
}

@Bean(name = "remoteNode2")
public RemoteNode getRemoteNode2() {

return new DefaultRemoteNode("NODE2");
}
}

org.xxx.repository.RemoteNodeRepository

@Repository
public class RemoteNodeRepositoryImpl implements RemoteNodeRepository {

private Map<String, RemoteNode> remoteNodeMap;

@Autowired
public RemoteNodeRepository(Map<String, RemoteNode> remoteNodeMap) {
this.remoteNodeMap = remoteNodeMap;
}
}

我期望注入(inject) RemoteNodeRepsoitory 的是一个如下所示的 Map:

"NODE1",RemoteNode("NODE1")

"NODE2",RemoteNode("NODE2")

但是,这是被注入(inject)到 RemoteNodeRepository 中的 Map:

"remoteNode1",RemoteNode("NODE1")

"remoteNode2",RemoteNode("NODE2")

注意,键的名称基于 Application 类中 @Bean 注释的名称。如果我们删除 @Bean 的“名称”限定符,则键将以方法命名。

如果我们将 @Qualifier 注释添加到 RemoteNodeRepsoitory 的 Map 属性中,我们会得到以下异常:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.chronopolis.remote.node.RemoteNode] found for dependency [map with value type org.chronopolis.remote.node.RemoteNode]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=remoteNodeMap)}

最后,当在调试器中设置断点时,我们可以清楚地看到 RemoteNodeRepository 在我们的 Application 类中调用 getRemoteNodeMap() 方法之前被实例化。

我们可以采取什么措施来解决这个计时问题?我很困惑。

最佳答案

我认为这不是时间问题。您与此 spring 功能“冲突”(来自 http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/ )

Even typed Maps can be autowired as long as the expected key type is String. The Map values will contain all beans of the expected type, and the keys will contain the corresponding bean names:

@Autowired
public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {
this.movieCatalogs = movieCatalogs;
}

说实话,我不确定你是否可以轻松地“覆盖”这个,但是简单的解决方法应该可行 - 只需使用一些包装类来使你的类型变得特殊 - 类似于(伪代码):

class NodeMap {
Map<String, RemoteNode> map;
}

然后在您的@Bean定义和 Autowiring 时使用它。或者只是不创建映射并使用 spring 功能(并且可能重命名您的节点 bean)。

关于java - Spring Boot 注解配置的时序问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30652933/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com