【问题标题】:Why bean definitions is stored in concurrent hashmap?为什么 bean 定义存储在并发 hashmap 中?
【发布时间】:2018-08-14 08:21:50
【问题描述】:

DefaultListableBeanFactory类中有

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

存储 bean 定义的位置。我是 Spring 新手,我不明白为什么 IoC 容器需要哈希图的并发性。据我了解,我们只是从 XML 文件中读取 bean 定义并将它们存储在 hashmap 中。

我们为什么不使用常规的HashMap 来达到目的?

【问题讨论】:

  • 因为HashMap 不是线程安全的? (此外,可以使用注释而不是 xml 来定义 bean,而且,AFAIK,这是现在更常见的方式)
  • 默认情况下spring中的所有bean都是Singleton。即应该只有一个bean实例。现在。假设您在两个不同的地方声明了同一个 bean。在 spring 启动期间,它会进行组件扫描并将所有 bean 放入此映射中。因此,如果两个线程扫描您创建的两个 bean,则两者都有可能被插入。如果发生这种情况,那么就有同一个 bean 的两个实例。我相信为了避免这些情况,使用线程安全映射
  • 我觉得跟单例关系不大。它更多的是关于将并行创建 bean 的 bean 注册代码。

标签: java spring ioc-container


【解决方案1】:

这是因为 bean 创建可以并行发生。因此,地图将成为关键数据。因此,如果对同一个键有任何更新,它是以串行模式而不是并行模式完成的。

这就是使用ConcurrentHashMap 的原因。现在是另一个问题,谁将并行注册 bean。因此,它可以是DefaultListableBeanFactory 的任何用户。所以为了让beanDefinitionMap上的所有操作线程安全ConcurrentHashMap已经使用了。

让我们通过例子来理解它:-

 private final DefaultListableBeanFactory factory = (DefaultListableBeanFactory) applicationContext
        .getAutowireCapableBeanFactory();

private void registerBean(String beanName, String scope) throws IOException {

    GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
    genericBeanDefinition.setBeanClassName("org.jibeframework.core.util.ViewComponentFactory");
    genericBeanDefinition.setScope(scope);
    genericBeanDefinition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_NO);
    genericBeanDefinition.setDependencyCheck(AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    BeanDefinitionHolder holder = new BeanDefinitionHolder(genericBeanDefinition, beanName, new String[] {});
    BeanDefinitionReaderUtils.registerBeanDefinition(holder, factory);

}

现在if this code is called inside a Thread 可能导致数据不一致、竞争条件等。这就是为什么DefaultListableBeanFactory 中的所有方法在执行registerBeanDefinition 之类的操作时也会获取不同的锁(together with using ConcurrentHashMap)。

查看 DefaultListableBeanFactory#registerBeanDefinition 以获得更清晰的信息。参考链接here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 2019-06-17
    • 2013-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多