Skip to content

Commit 4798da0

Browse files
committed
Avoid full synchronization in refreshable getBeanFactory() implementation
Closes gh-25081
1 parent 705157e commit 4798da0

File tree

1 file changed

+16
-26
lines changed

1 file changed

+16
-26
lines changed

spring-context/src/main/java/org/springframework/context/support/AbstractRefreshableApplicationContext.java

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -72,10 +72,7 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
7272

7373
/** Bean factory for this context */
7474
@Nullable
75-
private DefaultListableBeanFactory beanFactory;
76-
77-
/** Synchronization monitor for the internal BeanFactory */
78-
private final Object beanFactoryMonitor = new Object();
75+
private volatile DefaultListableBeanFactory beanFactory;
7976

8077

8178
/**
@@ -131,9 +128,7 @@ protected final void refreshBeanFactory() throws BeansException {
131128
beanFactory.setSerializationId(getId());
132129
customizeBeanFactory(beanFactory);
133130
loadBeanDefinitions(beanFactory);
134-
synchronized (this.beanFactoryMonitor) {
135-
this.beanFactory = beanFactory;
136-
}
131+
this.beanFactory = beanFactory;
137132
}
138133
catch (IOException ex) {
139134
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
@@ -142,21 +137,19 @@ protected final void refreshBeanFactory() throws BeansException {
142137

143138
@Override
144139
protected void cancelRefresh(BeansException ex) {
145-
synchronized (this.beanFactoryMonitor) {
146-
if (this.beanFactory != null) {
147-
this.beanFactory.setSerializationId(null);
148-
}
140+
DefaultListableBeanFactory beanFactory = this.beanFactory;
141+
if (beanFactory != null) {
142+
beanFactory.setSerializationId(null);
149143
}
150144
super.cancelRefresh(ex);
151145
}
152146

153147
@Override
154148
protected final void closeBeanFactory() {
155-
synchronized (this.beanFactoryMonitor) {
156-
if (this.beanFactory != null) {
157-
this.beanFactory.setSerializationId(null);
158-
this.beanFactory = null;
159-
}
149+
DefaultListableBeanFactory beanFactory = this.beanFactory;
150+
if (beanFactory != null) {
151+
beanFactory.setSerializationId(null);
152+
this.beanFactory = null;
160153
}
161154
}
162155

@@ -165,20 +158,17 @@ protected final void closeBeanFactory() {
165158
* i.e. has been refreshed at least once and not been closed yet.
166159
*/
167160
protected final boolean hasBeanFactory() {
168-
synchronized (this.beanFactoryMonitor) {
169-
return (this.beanFactory != null);
170-
}
161+
return (this.beanFactory != null);
171162
}
172163

173164
@Override
174165
public final ConfigurableListableBeanFactory getBeanFactory() {
175-
synchronized (this.beanFactoryMonitor) {
176-
if (this.beanFactory == null) {
177-
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
178-
"call 'refresh' before accessing beans via the ApplicationContext");
179-
}
180-
return this.beanFactory;
166+
DefaultListableBeanFactory beanFactory = this.beanFactory;
167+
if (beanFactory == null) {
168+
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
169+
"call 'refresh' before accessing beans via the ApplicationContext");
181170
}
171+
return beanFactory;
182172
}
183173

184174
/**

0 commit comments

Comments
 (0)