Skip to content

Commit c4f66b7

Browse files
committed
Use single volatile field for indicating pre-instantiation phase
See gh-34729
1 parent 87e04df commit c4f66b7

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

Diff for: spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

+19-11
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
218218
/** Whether bean definition metadata may be cached for all beans. */
219219
private volatile boolean configurationFrozen;
220220

221-
private volatile boolean preInstantiationPhase;
222-
221+
/** Name prefix of main thread: only set during pre-instantiation phase. */
223222
@Nullable
224223
private volatile String mainThreadPrefix;
225224

@@ -1066,26 +1065,37 @@ protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName
10661065
@Override
10671066
@Nullable
10681067
protected Boolean isCurrentThreadAllowedToHoldSingletonLock() {
1069-
if (this.preInstantiationPhase) {
1068+
String mainThreadPrefix = this.mainThreadPrefix;
1069+
if (this.mainThreadPrefix != null) {
10701070
// We only differentiate in the preInstantiateSingletons phase.
1071+
10711072
PreInstantiation preInstantiation = this.preInstantiationThread.get();
10721073
if (preInstantiation != null) {
1073-
// A Spring-managed thread:
1074+
// A Spring-managed bootstrap thread:
10741075
// MAIN is allowed to lock (true) or even forced to lock (null),
10751076
// BACKGROUND is never allowed to lock (false).
10761077
return switch (preInstantiation) {
10771078
case MAIN -> (Boolean.TRUE.equals(this.strictLocking) ? null : true);
10781079
case BACKGROUND -> false;
10791080
};
10801081
}
1081-
if (Boolean.FALSE.equals(this.strictLocking) ||
1082-
(this.strictLocking == null && !getThreadNamePrefix().equals(this.mainThreadPrefix))) {
1083-
// An unmanaged thread (assumed to be application-internal) with lenient locking,
1084-
// and not part of the same thread pool that provided the main bootstrap thread
1085-
// (excluding scenarios where we are hit by multiple external bootstrap threads).
1082+
1083+
// Not a Spring-managed bootstrap thread...
1084+
if (Boolean.FALSE.equals(this.strictLocking)) {
1085+
// Explicitly configured to use lenient locking wherever possible.
10861086
return true;
10871087
}
1088+
else if (this.strictLocking == null) {
1089+
// No explicit locking configuration -> infer appropriate locking.
1090+
if (mainThreadPrefix != null && !getThreadNamePrefix().equals(mainThreadPrefix)) {
1091+
// An unmanaged thread (assumed to be application-internal) with lenient locking,
1092+
// and not part of the same thread pool that provided the main bootstrap thread
1093+
// (excluding scenarios where we are hit by multiple external bootstrap threads).
1094+
return true;
1095+
}
1096+
}
10881097
}
1098+
10891099
// Traditional behavior: forced to always hold a full lock.
10901100
return null;
10911101
}
@@ -1103,7 +1113,6 @@ public void preInstantiateSingletons() throws BeansException {
11031113
// Trigger initialization of all non-lazy singleton beans...
11041114
List<CompletableFuture<?>> futures = new ArrayList<>();
11051115

1106-
this.preInstantiationPhase = true;
11071116
this.preInstantiationThread.set(PreInstantiation.MAIN);
11081117
this.mainThreadPrefix = getThreadNamePrefix();
11091118
try {
@@ -1120,7 +1129,6 @@ public void preInstantiateSingletons() throws BeansException {
11201129
finally {
11211130
this.mainThreadPrefix = null;
11221131
this.preInstantiationThread.remove();
1123-
this.preInstantiationPhase = false;
11241132
}
11251133

11261134
if (!futures.isEmpty()) {

0 commit comments

Comments
 (0)