【问题标题】:Spring bean map with dynamic keys and values具有动态键和值的 Spring bean 映射
【发布时间】:2013-02-04 15:21:22
【问题描述】:

现在我已经在 spring bean 映射中应用了相关数据,并将这个映射作为参考传递给其他类。

地图定义如下

<bean id="sampleMap" class="java.util.HashMap">
    <constructor-arg index="0" type="java.util.Map">
        <map key-type="java.lang.Integer" value-type="java.lang.Float">
            <entry key="1" value="5"/>
            <entry key="2" value="10"/>
            <entry key="3" value="15"/>             
        </map>
    </constructor-arg>
</bean>

此映射在其他 bean 中称为

<bean id="config" class="com.example.Config" abstract="false">      
    <property name="sampleMap" ref="sampleMap"/>
    .
    .
</bean>

我只想从数据库表中检索映射值并将其注入其他类。我怎么能在春天做到这一点。基本上该表包含与应用程序相关的数据。map 的键和值将是 int,Configuration。

加载配置数据的最佳位置是什么?我们可以使用 spring beans map 还是有任何其他好的方法来从数据库加载配置并将其引用到应用程序的其他地方,如服务、委托和 DAO?

我们将不胜感激

谢谢

【问题讨论】:

    标签: java spring hashmap spring-ioc


    【解决方案1】:

    你应该使用spring的FactoryBean

    public class MyHashMapFactoryBean implements FactoryBean<Map<Integer, Float>>{
    
      @Autowired
      private Datasource datasource; 
    
      public Map<Integer, Float> getObject(){
        return <load from database>;
      }
    
      public Class<Map> getObjectType() { return Map.class ; }
    
      public boolean isSingleton() { return true; }
    }
    
    <bean id="sampleMap" class="my.package.MyHashMapFactoryBean">
      <here you could pass some properties e.g. jdbc datasource>
    </bean>
    

    【讨论】:

      【解决方案2】:

      FactoryBean answer 是正确的,但 it's the old way of doing things

      改为使用@Configuration

      @Configuration
      public class DBConfiguration{
      
          @Autowired
          private DataSource dataSource;
      
          @Bean
          public Map<Integer, Float> configMap(){
              // use dataSource to get map values
          }
      
      }
      

      这种方法的众多优点之一是您可以将DataSource 自动装配到配置类中。

      顺便说一句,使用地图作为 bean 感觉不对。我会在地图周围创建一个包装器对象并将其用作 Spring Bean,但对此意见不一。

      【讨论】:

      • 工厂 bean 也可以自动装配。但是,是的,很高兴知道另一种方式。
      • @kan 是的,您可以自动装配 FactoryBean 本身,但不能自动装配它创建的 Bean。 FactoryBean 必须手动构造该 Bean。使用@Configuration@Bean(autowire=BY_NAME)(或BY_TYPE),您可以完全自动装配您在方法中创建的bean 对象。
      • 哦,对了。我没想到他可能需要自动装配地图。但在老式方式中,ApplicationContextAware 接口是可能的。
      • @kan 正如我所写,我认为他首先不应该使用地图作为 bean。而ApplicationContextAware 只会让您通过applicationContext.getAutowireCapableBeanFactory().autowireBean() 以编程方式自动装配bean,这比注释参数要多得多。但是为什么要和我争论呢,是 Spring 开发人员自己建议在上面的文章中使用 @Configuration 而不是 FactoryBean
      • 严格来说,如果他使用新类而不是 Map,他不需要工厂。类本身可以进行加载。无论如何,是的,Spring 3.1 有很好的特性。
      【解决方案3】:

      我今天实际发现的是,当您需要将 bean 名称映射到特定接口的实例时,不需要 @Qualifier 和任何类型的 FactoryBean 代码。 Spring 会为你找到并注入候选人。有点神奇,但它似乎是这样工作的。

      【讨论】:

        猜你喜欢
        • 2021-04-02
        • 1970-01-01
        • 2019-02-26
        • 2013-07-31
        • 1970-01-01
        • 2012-02-05
        • 2023-04-07
        • 2013-03-20
        • 1970-01-01
        相关资源
        最近更新 更多