在班级DefaultListableBeanFactory
有
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
存储bean定义的位置。我是Spring的新手,我不明白为什么IoC容器需要hashmap的并发性。据我所知,我们只是从XML文件中读取bean定义并将它们存储在hashmap中。
为什么我们不使用常规的HashMap
?
这是因为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
内的所有方法在执行像together with using ConcurrentHashMap
这样的操作时也获得不同的锁(registerBeanDefinition
)。
查看DefaultListableBeanFactory#registerBeanDefinition以获得更清晰的信息。一个参考链接here。