繁体   English   中英

Spring Boot注释配置的时序问题

[英]Timing Issue with Spring Boot Annotation Configuration

我们在Spring Boot应用程序中对bean,存储库和控制器的时间安排感到好奇。

我们有一个由地图支持的NodeRepository。 这个Map对象应该是我们使用@Bean批注创建的Map,但是似乎Spring正在创建自己的Map并将其注入到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;
    }
}

我希望注入到RemoteNodeRepsoitory中的是一个类似于以下内容的Map:

“NODE1”,REMOTENODE( “NODE1”)

“NODE2”,REMOTENODE( “NODE2”)

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

“remoteNode1”,REMOTENODE( “NODE1”)

“remoteNode2”,REMOTENODE( “NODE2”)

注意,键的名称基于Application类中@Bean批注的名称。 如果我们删除@Bean的'name'限定词,则以方法命名。

如果将@Qualifier批注添加到RemoteNodeRepsoitory的Map属性,则会得到以下异常:

由以下原因引起:org.springframework.beans.factory.NoSuchBeanDefinitionException:未找到依赖项[值为org.chronopolis.remote.node.RemoteNode的映射]类型为[org.chronopolis.remote.node.RemoteNode]的合格bean:预期在至少有1个符合该依赖项条件的自动装配候选bean。 依赖项注释:{@ org.springframework.beans.factory.annotation.Qualifier(value = remoteNodeMap)}

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

我们如何解决此计时问题? 我很困惑

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

只要预期的键类型为String,即使键入的Map也可以自动连线。 Map值将包含所有预期类型的​​bean,并且键将包含相应的bean名称:

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

老实说,我不确定您是否可以轻松地“重写”此方法,但是简单的解决方法应该可行-只需使用一些包装器类使您的类型特殊-类似于(伪代码):

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

然后在您的@Bean定义中以及自动@Bean时使用它。 或者只是不创建地图并使用spring功能(并可能重命名节点bean)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM