AbstractBeanFactory#markBeanAsCreated is that
protected void markBeanAsCreated(String beanName) {
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
clearMergedBeanDefinition(beanName);
this.alreadyCreated.add(beanName);
}
}
}
}
I think MergedBeanDefinitions have no relationship to alreadyCreated,so I think I should change the code to look like this:
protected void markBeanAsCreated(String beanName) {
synchronized (this.alreadyCreated) {
if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
clearMergedBeanDefinition(beanName);
this.alreadyCreated.add(beanName);
}
}
}
If I understand correctly, I would like to submit a PR,Thanks.
Comment From: jhoeller
This is intentional, just not very obvious I guess: The main purpose of this code is controlled clearing of the merged bean definition cache, so we're intentionally reusing the same lock as in getMergedBeanDefinition there.
alreadyCreated itself is a ConcurrentHashMap underneath its Set decorator, so contains can be called outside of a lock (which reduces thread contention on access). Jus for structural modifications to alreadyCreated, we're reusing the mergedBeanDefinitions lock in order to align its state with the mergedBeanDefinitions structure itself.