Spring Core中为何该代码行必须置于synchronized()代码块中?
this.beanFactory = beanFactory Needs to Be in a Synchronized Block in Spring's refreshBeanFactory Great question! Let's break down the key reasons this assignment is wrapped in synchronized(this.beanFactoryMonitor):
Guarantee thread visibility
ThebeanFactoryis an instance variable of theApplicationContext. Without synchronization, when one thread writes to this variable, the change might not be immediately visible to other threads due to CPU caching or JVM optimizations. The synchronized block acts as a memory barrier: it flushes the write to main memory, ensuring all subsequent reads from other threads will see the updatedbeanFactoryinstance, not a stale or null reference.Prevent race conditions with read operations
Spring'sgetBeanFactory()method (used to access the bean factory from other code) also locks on the samebeanFactoryMonitorfor synchronized reads. Here's the relevant source code for context:@Override public final ConfigurableListableBeanFactory getBeanFactory() { synchronized (this.beanFactoryMonitor) { if (this.beanFactory == null) { throw new IllegalStateException("BeanFactory not initialized or already closed - " + "call 'refresh' before accessing beans via the ApplicationContext"); } return this.beanFactory; } }By wrapping the write in the same lock, we ensure no thread can read the
beanFactorywhile it's being updated. This avoids scenarios where a thread might accidentally get a null or partially set-up bean factory if it callsgetBeanFactory()mid-refresh.Enforce a consistent happens-before relationship
Even though we fully initialize theDefaultListableBeanFactory(viacreateBeanFactory(),customizeBeanFactory(),loadBeanDefinitions()) before the assignment, the JVM could theoretically reorder instructions without synchronization. The synchronized block ensures all prior initialization steps are completed and visible before thebeanFactoryreference is updated, eliminating any risk of exposing a partially initialized instance.
In short, this synchronization is critical for maintaining thread safety in environments where the ApplicationContext might be accessed concurrently during or after the refresh process.
内容的提问来源于stack exchange,提问作者Young Chan

