From ff1e5a87b3ef452b480e775d3af7eda2d8bea0f8 Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Sat, 12 Jul 2025 16:22:35 +0200 Subject: [PATCH] Introduce ContextRestartedEvent as a subtype of ContextStartedEvent Prior to this commit, there was no way to differentiate between an ApplicationContext "start" and "restart" in terms of events. This was due to the fact that a ContextStartedEvent was fired for both AbstractApplicationContext.start() and AbstractApplicationContext.restart(). To assist developers who may wish to differentiate between "start" and "restart" events, this commit introduces a new ContextRestartedEvent as a subtype of ContextStartedEvent. In addition, AbstractApplicationContext.restart() now publishes a ContextRestartedEvent instead of a ContextStartedEvent. By making ContextRestartedEvent a subtype of ContextStartedEvent, applications can still expect ContextStoppedEvent/ContextStartedEvent event pairs for consistent lifecycle semantics, and they can optionally check if the ContextStartedEvent is a ContextRestartedEvent. Alternatively, applications can explicitly react to a ContextRestartedEvent. See gh-35168 See gh-35171 Closes gh-35194 --- .../context/event/ContextRestartedEvent.java | 44 +++++++++++++++++++ .../context/event/ContextStartedEvent.java | 1 + .../context/event/ContextStoppedEvent.java | 1 + .../support/AbstractApplicationContext.java | 3 +- 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 spring-context/src/main/java/org/springframework/context/event/ContextRestartedEvent.java diff --git a/spring-context/src/main/java/org/springframework/context/event/ContextRestartedEvent.java b/spring-context/src/main/java/org/springframework/context/event/ContextRestartedEvent.java new file mode 100644 index 00000000000..e8165be8d08 --- /dev/null +++ b/spring-context/src/main/java/org/springframework/context/event/ContextRestartedEvent.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002-present 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.event; + +import org.springframework.context.ApplicationContext; + +/** + * Event raised when an {@code ApplicationContext} gets restarted. + * + *

Note that {@code ContextRestartedEvent} is a specialization of + * {@link ContextStartedEvent}. + * + * @author Sam Brannen + * @since 7.0 + * @see ContextStartedEvent + * @see ContextStoppedEvent + */ +@SuppressWarnings("serial") +public class ContextRestartedEvent extends ContextStartedEvent { + + /** + * Create a new {@code ContextRestartedEvent}. + * @param source the {@code ApplicationContext} that has been restarted + * (must not be {@code null}) + */ + public ContextRestartedEvent(ApplicationContext source) { + super(source); + } + +} diff --git a/spring-context/src/main/java/org/springframework/context/event/ContextStartedEvent.java b/spring-context/src/main/java/org/springframework/context/event/ContextStartedEvent.java index b67513815ac..d304b07c97a 100644 --- a/spring-context/src/main/java/org/springframework/context/event/ContextStartedEvent.java +++ b/spring-context/src/main/java/org/springframework/context/event/ContextStartedEvent.java @@ -24,6 +24,7 @@ import org.springframework.context.ApplicationContext; * @author Mark Fisher * @author Juergen Hoeller * @since 2.5 + * @see ContextRestartedEvent * @see ContextStoppedEvent */ @SuppressWarnings("serial") diff --git a/spring-context/src/main/java/org/springframework/context/event/ContextStoppedEvent.java b/spring-context/src/main/java/org/springframework/context/event/ContextStoppedEvent.java index 76d241d2bb4..0a18921556c 100644 --- a/spring-context/src/main/java/org/springframework/context/event/ContextStoppedEvent.java +++ b/spring-context/src/main/java/org/springframework/context/event/ContextStoppedEvent.java @@ -25,6 +25,7 @@ import org.springframework.context.ApplicationContext; * @author Juergen Hoeller * @since 2.5 * @see ContextStartedEvent + * @see ContextRestartedEvent */ @SuppressWarnings("serial") public class ContextStoppedEvent extends ApplicationContextEvent { diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index 2daed0cee3e..05d8f8ddd3e 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -67,6 +67,7 @@ import org.springframework.context.ResourceLoaderAware; import org.springframework.context.event.ApplicationEventMulticaster; import org.springframework.context.event.ContextClosedEvent; import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.context.event.ContextRestartedEvent; import org.springframework.context.event.ContextStartedEvent; import org.springframework.context.event.ContextStoppedEvent; import org.springframework.context.event.SimpleApplicationEventMulticaster; @@ -1551,7 +1552,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader @Override public void restart() { getLifecycleProcessor().onRestart(); - publishEvent(new ContextStartedEvent(this)); + publishEvent(new ContextRestartedEvent(this)); } @Override