Browse Source

Synchronized onRefresh execution for concurrent ContextRefreshedEvent

Issue: SPR-17442

(cherry picked from commit b1f5f51503)
pull/2028/head
Juergen Hoeller 7 years ago
parent
commit
88f4e9205a
  1. 23
      spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java

23
spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java

@ -213,7 +213,10 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
private boolean webApplicationContextInjected = false; private boolean webApplicationContextInjected = false;
/** Flag used to detect whether onRefresh has already been called */ /** Flag used to detect whether onRefresh has already been called */
private boolean refreshEventReceived = false; private volatile boolean refreshEventReceived = false;
/** Monitor for synchronized onRefresh execution */
private final Object onRefreshMonitor = new Object();
/** /**
@ -490,8 +493,8 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
@Override @Override
protected final void initServletBean() throws ServletException { protected final void initServletBean() throws ServletException {
getServletContext().log("Initializing Spring FrameworkServlet '" + getServletName() + "'"); getServletContext().log("Initializing Spring FrameworkServlet '" + getServletName() + "'");
if (this.logger.isInfoEnabled()) { if (logger.isInfoEnabled()) {
this.logger.info("FrameworkServlet '" + getServletName() + "': initialization started"); logger.info("FrameworkServlet '" + getServletName() + "': initialization started");
} }
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
@ -500,13 +503,13 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
initFrameworkServlet(); initFrameworkServlet();
} }
catch (ServletException | RuntimeException ex) { catch (ServletException | RuntimeException ex) {
this.logger.error("Context initialization failed", ex); logger.error("Context initialization failed", ex);
throw ex; throw ex;
} }
if (this.logger.isInfoEnabled()) { if (logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime; long elapsedTime = System.currentTimeMillis() - startTime;
this.logger.info("FrameworkServlet '" + getServletName() + "': initialization completed in " + logger.info("FrameworkServlet '" + getServletName() + "': initialization completed in " +
elapsedTime + " ms"); elapsedTime + " ms");
} }
} }
@ -558,7 +561,9 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
// Either the context is not a ConfigurableApplicationContext with refresh // Either the context is not a ConfigurableApplicationContext with refresh
// support or the context injected at construction time had already been // support or the context injected at construction time had already been
// refreshed -> trigger initial onRefresh manually here. // refreshed -> trigger initial onRefresh manually here.
onRefresh(wac); synchronized (this.onRefreshMonitor) {
onRefresh(wac);
}
} }
if (this.publishContext) { if (this.publishContext) {
@ -808,7 +813,9 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
*/ */
public void onApplicationEvent(ContextRefreshedEvent event) { public void onApplicationEvent(ContextRefreshedEvent event) {
this.refreshEventReceived = true; this.refreshEventReceived = true;
onRefresh(event.getApplicationContext()); synchronized (this.onRefreshMonitor) {
onRefresh(event.getApplicationContext());
}
} }
/** /**

Loading…
Cancel
Save