Browse Source

Avoid full synchronization in refreshable getBeanFactory() implementation

Closes gh-25219
pull/25592/head
Juergen Hoeller 6 years ago
parent
commit
31cda09c93
  1. 37
      spring-context/src/main/java/org/springframework/context/support/AbstractRefreshableApplicationContext.java

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

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -68,10 +68,7 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
private Boolean allowCircularReferences; private Boolean allowCircularReferences;
/** Bean factory for this context */ /** Bean factory for this context */
private DefaultListableBeanFactory beanFactory; private volatile DefaultListableBeanFactory beanFactory;
/** Synchronization monitor for the internal BeanFactory */
private final Object beanFactoryMonitor = new Object();
/** /**
@ -127,9 +124,7 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
beanFactory.setSerializationId(getId()); beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory); customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory); loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory;
this.beanFactory = beanFactory;
}
} }
catch (IOException ex) { catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
@ -138,17 +133,18 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
@Override @Override
protected void cancelRefresh(BeansException ex) { protected void cancelRefresh(BeansException ex) {
synchronized (this.beanFactoryMonitor) { DefaultListableBeanFactory beanFactory = this.beanFactory;
if (this.beanFactory != null) if (beanFactory != null) {
this.beanFactory.setSerializationId(null); beanFactory.setSerializationId(null);
} }
super.cancelRefresh(ex); super.cancelRefresh(ex);
} }
@Override @Override
protected final void closeBeanFactory() { protected final void closeBeanFactory() {
synchronized (this.beanFactoryMonitor) { DefaultListableBeanFactory beanFactory = this.beanFactory;
this.beanFactory.setSerializationId(null); if (beanFactory != null) {
beanFactory.setSerializationId(null);
this.beanFactory = null; this.beanFactory = null;
} }
} }
@ -158,20 +154,17 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
* i.e. has been refreshed at least once and not been closed yet. * i.e. has been refreshed at least once and not been closed yet.
*/ */
protected final boolean hasBeanFactory() { protected final boolean hasBeanFactory() {
synchronized (this.beanFactoryMonitor) { return (this.beanFactory != null);
return (this.beanFactory != null);
}
} }
@Override @Override
public final ConfigurableListableBeanFactory getBeanFactory() { public final ConfigurableListableBeanFactory getBeanFactory() {
synchronized (this.beanFactoryMonitor) { DefaultListableBeanFactory beanFactory = this.beanFactory;
if (this.beanFactory == null) { if (beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " + throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext"); "call 'refresh' before accessing beans via the ApplicationContext");
}
return this.beanFactory;
} }
return beanFactory;
} }
/** /**

Loading…
Cancel
Save