From 5804659725333b064ea11cfec33078029f5231ed Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 18 May 2020 14:22:24 +0200 Subject: [PATCH] Avoid full synchronization in refreshable getBeanFactory() implementation Closes gh-25081 --- ...AbstractRefreshableApplicationContext.java | 42 +++++++------------ 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractRefreshableApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractRefreshableApplicationContext.java index e4996495bf06..b22be62ae46b 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractRefreshableApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractRefreshableApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,10 +72,7 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl /** Bean factory for this context. */ @Nullable - private DefaultListableBeanFactory beanFactory; - - /** Synchronization monitor for the internal BeanFactory. */ - private final Object beanFactoryMonitor = new Object(); + private volatile DefaultListableBeanFactory beanFactory; /** @@ -134,9 +131,7 @@ protected final void refreshBeanFactory() throws BeansException { customizeBeanFactory(beanFactory); //加载BeanDefinition信息 loadBeanDefinitions(beanFactory); - synchronized (this.beanFactoryMonitor) { - this.beanFactory = beanFactory; - } + this.beanFactory = beanFactory; } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); @@ -145,21 +140,19 @@ protected final void refreshBeanFactory() throws BeansException { @Override protected void cancelRefresh(BeansException ex) { - synchronized (this.beanFactoryMonitor) { - if (this.beanFactory != null) { - this.beanFactory.setSerializationId(null); - } + DefaultListableBeanFactory beanFactory = this.beanFactory; + if (beanFactory != null) { + beanFactory.setSerializationId(null); } super.cancelRefresh(ex); } @Override protected final void closeBeanFactory() { - synchronized (this.beanFactoryMonitor) { - if (this.beanFactory != null) { - this.beanFactory.setSerializationId(null); - this.beanFactory = null; - } + DefaultListableBeanFactory beanFactory = this.beanFactory; + if (beanFactory != null) { + beanFactory.setSerializationId(null); + this.beanFactory = null; } } @@ -168,20 +161,17 @@ protected final void closeBeanFactory() { * i.e. has been refreshed at least once and not been closed yet. */ protected final boolean hasBeanFactory() { - synchronized (this.beanFactoryMonitor) { - return (this.beanFactory != null); - } + return (this.beanFactory != null); } @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; + DefaultListableBeanFactory beanFactory = this.beanFactory; + if (beanFactory == null) { + throw new IllegalStateException("BeanFactory not initialized or already closed - " + + "call 'refresh' before accessing beans via the ApplicationContext"); } + return beanFactory; } /**