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.