diff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-nature.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-nature.adoc index c23676f938e..7ed7cd01182 100644 --- a/framework-docs/modules/ROOT/pages/core/beans/factory-nature.adoc +++ b/framework-docs/modules/ROOT/pages/core/beans/factory-nature.adoc @@ -592,6 +592,40 @@ Kotlin:: +[[beans-factory-thread-safety]] +=== Thread Safety and Visibility + +The Spring core container publishes created singleton instances in a thread-safe manner, +guarding access through a singleton lock and guaranteeing visibility in other threads. + +As a consequence, application-provided bean classes do not have to be concerned about the +visibility of their initialization state. Regular configuration fields do not have to be +marked as `volatile` as long as they are only mutated during the initialization phase, +providing visibility guarantees similar to `final` even for setter-based configuration +state that is mutable during that initial phase. If such fields get changed after the +bean creation phase and its subsequent initial publication, they need to be declared as +`volatile` or guarded by a common lock whenever accessed. + +Note that concurrent access to such configuration state in singleton bean instances, +e.g. for controller instances or repository instances, is perfectly thread-safe after +such safe initial publication from the container side. This includes common singleton +`FactoryBean` instances which are processed within the general singleton lock as well. + +For destruction callbacks, the configuration state remains thread-safe but any runtime +state accumulated between initialization and destruction should be kept in thread-safe +structures (or in `volatile` fields for simple cases) as per common Java guidelines. + +Deeper `Lifecycle` integration as shown above involves runtime-mutable state such as +a `runnable` field which will have to be declared as `volatile`. While the common +lifecycle callbacks follow a certain order, e.g. a start callback is guaranteed to +only happen after full initialization and a stop callback only after an initial start, +there is a special case with the common stop before destroy arrangement: It is strongly +recommended that the internal state in any such bean also allows for an immediate +destroy callback without a preceding stop since this may happen during an extraordinary +shutdown after a cancelled bootstrap or in case of a stop timeout caused by another bean. + + + [[beans-factory-aware]] == `ApplicationContextAware` and `BeanNameAware`