Support for Project CRaC in DefaultLifecycleProcessor
Includes stopForRestart/restartAfterStop functionality. Closes gh-30242
This commit is contained in:
parent
4db724984e
commit
8d604350e4
|
@ -110,6 +110,7 @@ dependencies {
|
|||
api("org.awaitility:awaitility:4.2.0")
|
||||
api("org.bouncycastle:bcpkix-jdk18on:1.72")
|
||||
api("org.codehaus.jettison:jettison:1.5.4")
|
||||
api("org.crac:crac:0.1.3")
|
||||
api("org.dom4j:dom4j:2.1.4")
|
||||
api("org.eclipse.jetty:jetty-reactive-httpclient:3.0.8")
|
||||
api("org.eclipse.persistence:org.eclipse.persistence.jpa:3.0.3")
|
||||
|
|
|
@ -22,6 +22,7 @@ dependencies {
|
|||
optional("org.aspectj:aspectjweaver")
|
||||
optional("org.apache.groovy:groovy")
|
||||
optional("org.apache-extras.beanshell:bsh")
|
||||
optional("org.crac:crac")
|
||||
optional("org.hibernate:hibernate-validator")
|
||||
optional("org.jetbrains.kotlin:kotlin-reflect")
|
||||
optional("org.jetbrains.kotlin:kotlin-stdlib")
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -43,16 +44,25 @@ import org.springframework.context.Phased;
|
|||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link LifecycleProcessor} strategy.
|
||||
*
|
||||
* <p>Provides interaction with {@link Lifecycle} and {@link SmartLifecycle} beans in
|
||||
* groups for specific phases, on startup/shutdown as well as for explicit start/stop
|
||||
* interactions on a {@link org.springframework.context.ConfigurableApplicationContext}.
|
||||
* As of 6.1, this also includes support for JVM snapshot checkpoints (Project CRaC).
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactoryAware {
|
||||
|
||||
private static final boolean cracPresent =
|
||||
ClassUtils.isPresent("org.crac.Core", DefaultLifecycleProcessor.class.getClassLoader());
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private volatile long timeoutPerShutdownPhase = 30000;
|
||||
|
@ -62,6 +72,16 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||
@Nullable
|
||||
private volatile ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
@Nullable
|
||||
private volatile Set<String> stoppedBeans;
|
||||
|
||||
|
||||
public DefaultLifecycleProcessor() {
|
||||
if (cracPresent) {
|
||||
new CracDelegate().registerResource();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify the maximum time allotted in milliseconds for the shutdown of
|
||||
|
@ -100,6 +120,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||
*/
|
||||
@Override
|
||||
public void start() {
|
||||
this.stoppedBeans = null;
|
||||
startBeans(false);
|
||||
this.running = true;
|
||||
}
|
||||
|
@ -120,6 +141,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
this.stoppedBeans = null;
|
||||
startBeans(true);
|
||||
this.running = true;
|
||||
}
|
||||
|
@ -138,12 +160,28 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||
|
||||
// Internal helpers
|
||||
|
||||
void stopForRestart() {
|
||||
if (this.running) {
|
||||
this.stoppedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
stopBeans();
|
||||
this.running = false;
|
||||
}
|
||||
}
|
||||
|
||||
void restartAfterStop() {
|
||||
if (this.stoppedBeans != null) {
|
||||
startBeans(true);
|
||||
this.stoppedBeans = null;
|
||||
this.running = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void startBeans(boolean autoStartupOnly) {
|
||||
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
|
||||
Map<Integer, LifecycleGroup> phases = new TreeMap<>();
|
||||
|
||||
lifecycleBeans.forEach((beanName, bean) -> {
|
||||
if (!autoStartupOnly || (bean instanceof SmartLifecycle smartLifecycle && smartLifecycle.isAutoStartup())) {
|
||||
if (!autoStartupOnly || isAutoStartupCandidate(beanName, bean)) {
|
||||
int phase = getPhase(bean);
|
||||
phases.computeIfAbsent(
|
||||
phase,
|
||||
|
@ -156,6 +194,12 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isAutoStartupCandidate(String beanName, Lifecycle bean) {
|
||||
Set<String> stoppedBeans = this.stoppedBeans;
|
||||
return (stoppedBeans != null ? stoppedBeans.contains(beanName) :
|
||||
(bean instanceof SmartLifecycle smartLifecycle && smartLifecycle.isAutoStartup()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the specified bean as part of the given set of Lifecycle beans,
|
||||
* making sure that any beans that it depends on are started first.
|
||||
|
@ -169,8 +213,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||
for (String dependency : dependenciesForBean) {
|
||||
doStart(lifecycleBeans, dependency, autoStartupOnly);
|
||||
}
|
||||
if (!bean.isRunning() &&
|
||||
(!autoStartupOnly || !(bean instanceof SmartLifecycle smartLifecycle) || smartLifecycle.isAutoStartup())) {
|
||||
if (!bean.isRunning() && (!autoStartupOnly || toBeStarted(beanName, bean))) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Starting bean '" + beanName + "' of type [" + bean.getClass().getName() + "]");
|
||||
}
|
||||
|
@ -187,6 +230,12 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||
}
|
||||
}
|
||||
|
||||
private boolean toBeStarted(String beanName, Lifecycle bean) {
|
||||
Set<String> stoppedBeans = this.stoppedBeans;
|
||||
return (stoppedBeans != null ? stoppedBeans.contains(beanName) :
|
||||
(!(bean instanceof SmartLifecycle smartLifecycle) || smartLifecycle.isAutoStartup()));
|
||||
}
|
||||
|
||||
private void stopBeans() {
|
||||
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
|
||||
Map<Integer, LifecycleGroup> phases = new TreeMap<>(Comparator.reverseOrder());
|
||||
|
@ -219,6 +268,10 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||
}
|
||||
try {
|
||||
if (bean.isRunning()) {
|
||||
Set<String> stoppedBeans = this.stoppedBeans;
|
||||
if (stoppedBeans != null) {
|
||||
stoppedBeans.add(beanName);
|
||||
}
|
||||
if (bean instanceof SmartLifecycle smartLifecycle) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Asking bean '" + beanName + "' of type [" +
|
||||
|
@ -391,4 +444,41 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||
*/
|
||||
private record LifecycleGroupMember(String name, Lifecycle bean) {}
|
||||
|
||||
|
||||
/**
|
||||
* Inner class to avoid a hard dependency on Project CRaC at runtime.
|
||||
* @since 6.1
|
||||
* @see org.crac.Core
|
||||
*/
|
||||
private class CracDelegate {
|
||||
|
||||
public void registerResource() {
|
||||
logger.debug("Registering JVM snapshot callback for Spring-managed lifecycle beans");
|
||||
org.crac.Core.getGlobalContext().register(new CracResourceAdapter());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resource adapter for Project CRaC, triggering a stop-and-restart cycle
|
||||
* for Spring-managed lifecycle beans around a JVM snapshot checkpoint.
|
||||
* @since 6.1
|
||||
* @see #stopForRestart()
|
||||
* @see #restartAfterStop()
|
||||
*/
|
||||
private class CracResourceAdapter implements org.crac.Resource {
|
||||
|
||||
@Override
|
||||
public void beforeCheckpoint(org.crac.Context<? extends org.crac.Resource> context) {
|
||||
logger.debug("Stopping Spring-managed lifecycle beans before JVM snapshot checkpoint");
|
||||
stopForRestart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterRestore(org.crac.Context<? extends org.crac.Resource> context) {
|
||||
logger.debug("Restarting Spring-managed lifecycle beans after JVM snapshot restore");
|
||||
restartAfterStop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
|
@ -34,6 +34,7 @@ import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING;
|
|||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
class DefaultLifecycleProcessorTests {
|
||||
|
@ -58,12 +59,12 @@ class DefaultLifecycleProcessorTests {
|
|||
Object contextLifecycleProcessor = new DirectFieldAccessor(context).getPropertyValue("lifecycleProcessor");
|
||||
assertThat(contextLifecycleProcessor).isNotNull();
|
||||
assertThat(contextLifecycleProcessor).isSameAs(bean);
|
||||
assertThat(new DirectFieldAccessor(contextLifecycleProcessor).getPropertyValue(
|
||||
"timeoutPerShutdownPhase")).isEqualTo(1000L);
|
||||
assertThat(new DirectFieldAccessor(contextLifecycleProcessor).getPropertyValue("timeoutPerShutdownPhase"))
|
||||
.isEqualTo(1000L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void singleSmartLifecycleAutoStartup() throws Exception {
|
||||
void singleSmartLifecycleAutoStartup() {
|
||||
CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<>();
|
||||
TestSmartLifecycleBean bean = TestSmartLifecycleBean.forStartupTests(1, startedBeans);
|
||||
bean.setAutoStartup(true);
|
||||
|
@ -79,7 +80,7 @@ class DefaultLifecycleProcessorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void singleSmartLifecycleAutoStartupWithLazyInit() throws Exception {
|
||||
void singleSmartLifecycleAutoStartupWithLazyInit() {
|
||||
StaticApplicationContext context = new StaticApplicationContext();
|
||||
RootBeanDefinition bd = new RootBeanDefinition(DummySmartLifecycleBean.class);
|
||||
bd.setLazyInit(true);
|
||||
|
@ -93,7 +94,7 @@ class DefaultLifecycleProcessorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void singleSmartLifecycleAutoStartupWithLazyInitFactoryBean() throws Exception {
|
||||
void singleSmartLifecycleAutoStartupWithLazyInitFactoryBean() {
|
||||
StaticApplicationContext context = new StaticApplicationContext();
|
||||
RootBeanDefinition bd = new RootBeanDefinition(DummySmartLifecycleFactoryBean.class);
|
||||
bd.setLazyInit(true);
|
||||
|
@ -107,7 +108,7 @@ class DefaultLifecycleProcessorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void singleSmartLifecycleWithoutAutoStartup() throws Exception {
|
||||
void singleSmartLifecycleWithoutAutoStartup() {
|
||||
CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<>();
|
||||
TestSmartLifecycleBean bean = TestSmartLifecycleBean.forStartupTests(1, startedBeans);
|
||||
bean.setAutoStartup(false);
|
||||
|
@ -125,7 +126,7 @@ class DefaultLifecycleProcessorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void singleSmartLifecycleAutoStartupWithNonAutoStartupDependency() throws Exception {
|
||||
void singleSmartLifecycleAutoStartupWithNonAutoStartupDependency() {
|
||||
CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<>();
|
||||
TestSmartLifecycleBean bean = TestSmartLifecycleBean.forStartupTests(1, startedBeans);
|
||||
bean.setAutoStartup(true);
|
||||
|
@ -148,7 +149,7 @@ class DefaultLifecycleProcessorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void smartLifecycleGroupStartup() throws Exception {
|
||||
void smartLifecycleGroupStartup() {
|
||||
CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<>();
|
||||
TestSmartLifecycleBean beanMin = TestSmartLifecycleBean.forStartupTests(Integer.MIN_VALUE, startedBeans);
|
||||
TestSmartLifecycleBean bean1 = TestSmartLifecycleBean.forStartupTests(1, startedBeans);
|
||||
|
@ -183,7 +184,7 @@ class DefaultLifecycleProcessorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void contextRefreshThenStartWithMixedBeans() throws Exception {
|
||||
void contextRefreshThenStartWithMixedBeans() {
|
||||
CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<>();
|
||||
TestLifecycleBean simpleBean1 = TestLifecycleBean.forStartupTests(startedBeans);
|
||||
TestLifecycleBean simpleBean2 = TestLifecycleBean.forStartupTests(startedBeans);
|
||||
|
@ -218,7 +219,7 @@ class DefaultLifecycleProcessorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void contextRefreshThenStopAndRestartWithMixedBeans() throws Exception {
|
||||
void contextRefreshThenStopAndRestartWithMixedBeans() {
|
||||
CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<>();
|
||||
TestLifecycleBean simpleBean1 = TestLifecycleBean.forStartupTests(startedBeans);
|
||||
TestLifecycleBean simpleBean2 = TestLifecycleBean.forStartupTests(startedBeans);
|
||||
|
@ -259,9 +260,62 @@ class DefaultLifecycleProcessorTests {
|
|||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextRefreshThenStopForRestartWithMixedBeans() {
|
||||
CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<>();
|
||||
TestLifecycleBean simpleBean1 = TestLifecycleBean.forStartupTests(startedBeans);
|
||||
TestLifecycleBean simpleBean2 = TestLifecycleBean.forStartupTests(startedBeans);
|
||||
TestSmartLifecycleBean smartBean1 = TestSmartLifecycleBean.forStartupTests(5, startedBeans);
|
||||
TestSmartLifecycleBean smartBean2 = TestSmartLifecycleBean.forStartupTests(-3, startedBeans);
|
||||
StaticApplicationContext context = new StaticApplicationContext();
|
||||
context.getBeanFactory().registerSingleton("simpleBean1", simpleBean1);
|
||||
context.getBeanFactory().registerSingleton("smartBean1", smartBean1);
|
||||
context.getBeanFactory().registerSingleton("simpleBean2", simpleBean2);
|
||||
context.getBeanFactory().registerSingleton("smartBean2", smartBean2);
|
||||
assertThat(simpleBean1.isRunning()).isFalse();
|
||||
assertThat(simpleBean2.isRunning()).isFalse();
|
||||
assertThat(smartBean1.isRunning()).isFalse();
|
||||
assertThat(smartBean2.isRunning()).isFalse();
|
||||
context.refresh();
|
||||
DefaultLifecycleProcessor lifecycleProcessor = (DefaultLifecycleProcessor)
|
||||
new DirectFieldAccessor(context).getPropertyValue("lifecycleProcessor");
|
||||
assertThat(smartBean1.isRunning()).isTrue();
|
||||
assertThat(smartBean2.isRunning()).isTrue();
|
||||
assertThat(simpleBean1.isRunning()).isFalse();
|
||||
assertThat(simpleBean2.isRunning()).isFalse();
|
||||
smartBean2.stop();
|
||||
simpleBean1.start();
|
||||
assertThat(startedBeans).hasSize(3);
|
||||
assertThat(getPhase(startedBeans.get(0))).isEqualTo(-3);
|
||||
assertThat(getPhase(startedBeans.get(1))).isEqualTo(5);
|
||||
assertThat(getPhase(startedBeans.get(2))).isEqualTo(0);
|
||||
lifecycleProcessor.stopForRestart();
|
||||
assertThat(simpleBean1.isRunning()).isFalse();
|
||||
assertThat(simpleBean2.isRunning()).isFalse();
|
||||
assertThat(smartBean1.isRunning()).isFalse();
|
||||
assertThat(smartBean2.isRunning()).isFalse();
|
||||
lifecycleProcessor.restartAfterStop();
|
||||
assertThat(smartBean1.isRunning()).isTrue();
|
||||
assertThat(smartBean2.isRunning()).isFalse();
|
||||
assertThat(simpleBean1.isRunning()).isTrue();
|
||||
assertThat(simpleBean2.isRunning()).isFalse();
|
||||
assertThat(startedBeans).hasSize(5);
|
||||
assertThat(getPhase(startedBeans.get(3))).isEqualTo(0);
|
||||
assertThat(getPhase(startedBeans.get(4))).isEqualTo(5);
|
||||
context.start();
|
||||
assertThat(smartBean1.isRunning()).isTrue();
|
||||
assertThat(smartBean2.isRunning()).isTrue();
|
||||
assertThat(simpleBean1.isRunning()).isTrue();
|
||||
assertThat(simpleBean2.isRunning()).isTrue();
|
||||
assertThat(startedBeans).hasSize(7);
|
||||
assertThat(getPhase(startedBeans.get(5))).isEqualTo(-3);
|
||||
assertThat(getPhase(startedBeans.get(6))).isEqualTo(0);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
void smartLifecycleGroupShutdown() throws Exception {
|
||||
void smartLifecycleGroupShutdown() {
|
||||
CopyOnWriteArrayList<Lifecycle> stoppedBeans = new CopyOnWriteArrayList<>();
|
||||
TestSmartLifecycleBean bean1 = TestSmartLifecycleBean.forShutdownTests(1, 300, stoppedBeans);
|
||||
TestSmartLifecycleBean bean2 = TestSmartLifecycleBean.forShutdownTests(3, 100, stoppedBeans);
|
||||
|
@ -292,7 +346,7 @@ class DefaultLifecycleProcessorTests {
|
|||
|
||||
@Test
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
void singleSmartLifecycleShutdown() throws Exception {
|
||||
void singleSmartLifecycleShutdown() {
|
||||
CopyOnWriteArrayList<Lifecycle> stoppedBeans = new CopyOnWriteArrayList<>();
|
||||
TestSmartLifecycleBean bean = TestSmartLifecycleBean.forShutdownTests(99, 300, stoppedBeans);
|
||||
StaticApplicationContext context = new StaticApplicationContext();
|
||||
|
@ -307,7 +361,7 @@ class DefaultLifecycleProcessorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void singleLifecycleShutdown() throws Exception {
|
||||
void singleLifecycleShutdown() {
|
||||
CopyOnWriteArrayList<Lifecycle> stoppedBeans = new CopyOnWriteArrayList<>();
|
||||
Lifecycle bean = new TestLifecycleBean(null, stoppedBeans);
|
||||
StaticApplicationContext context = new StaticApplicationContext();
|
||||
|
@ -324,7 +378,7 @@ class DefaultLifecycleProcessorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void mixedShutdown() throws Exception {
|
||||
void mixedShutdown() {
|
||||
CopyOnWriteArrayList<Lifecycle> stoppedBeans = new CopyOnWriteArrayList<>();
|
||||
Lifecycle bean1 = TestLifecycleBean.forShutdownTests(stoppedBeans);
|
||||
Lifecycle bean2 = TestSmartLifecycleBean.forShutdownTests(500, 200, stoppedBeans);
|
||||
|
@ -373,7 +427,7 @@ class DefaultLifecycleProcessorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void dependencyStartedFirstEvenIfItsPhaseIsHigher() throws Exception {
|
||||
void dependencyStartedFirstEvenIfItsPhaseIsHigher() {
|
||||
CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<>();
|
||||
TestSmartLifecycleBean beanMin = TestSmartLifecycleBean.forStartupTests(Integer.MIN_VALUE, startedBeans);
|
||||
TestSmartLifecycleBean bean2 = TestSmartLifecycleBean.forStartupTests(2, startedBeans);
|
||||
|
@ -403,7 +457,7 @@ class DefaultLifecycleProcessorTests {
|
|||
|
||||
@Test
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
void dependentShutdownFirstEvenIfItsPhaseIsLower() throws Exception {
|
||||
void dependentShutdownFirstEvenIfItsPhaseIsLower() {
|
||||
CopyOnWriteArrayList<Lifecycle> stoppedBeans = new CopyOnWriteArrayList<>();
|
||||
TestSmartLifecycleBean beanMin = TestSmartLifecycleBean.forShutdownTests(Integer.MIN_VALUE, 100, stoppedBeans);
|
||||
TestSmartLifecycleBean bean1 = TestSmartLifecycleBean.forShutdownTests(1, 200, stoppedBeans);
|
||||
|
@ -446,7 +500,7 @@ class DefaultLifecycleProcessorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void dependencyStartedFirstAndIsSmartLifecycle() throws Exception {
|
||||
void dependencyStartedFirstAndIsSmartLifecycle() {
|
||||
CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<>();
|
||||
TestSmartLifecycleBean beanNegative = TestSmartLifecycleBean.forStartupTests(-99, startedBeans);
|
||||
TestSmartLifecycleBean bean99 = TestSmartLifecycleBean.forStartupTests(99, startedBeans);
|
||||
|
@ -478,7 +532,7 @@ class DefaultLifecycleProcessorTests {
|
|||
|
||||
@Test
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
void dependentShutdownFirstAndIsSmartLifecycle() throws Exception {
|
||||
void dependentShutdownFirstAndIsSmartLifecycle() {
|
||||
CopyOnWriteArrayList<Lifecycle> stoppedBeans = new CopyOnWriteArrayList<>();
|
||||
TestSmartLifecycleBean beanMin = TestSmartLifecycleBean.forShutdownTests(Integer.MIN_VALUE, 400, stoppedBeans);
|
||||
TestSmartLifecycleBean beanNegative = TestSmartLifecycleBean.forShutdownTests(-99, 100, stoppedBeans);
|
||||
|
@ -520,7 +574,7 @@ class DefaultLifecycleProcessorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void dependencyStartedFirstButNotSmartLifecycle() throws Exception {
|
||||
void dependencyStartedFirstButNotSmartLifecycle() {
|
||||
CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<>();
|
||||
TestSmartLifecycleBean beanMin = TestSmartLifecycleBean.forStartupTests(Integer.MIN_VALUE, startedBeans);
|
||||
TestSmartLifecycleBean bean7 = TestSmartLifecycleBean.forStartupTests(7, startedBeans);
|
||||
|
@ -544,7 +598,7 @@ class DefaultLifecycleProcessorTests {
|
|||
|
||||
@Test
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
void dependentShutdownFirstButNotSmartLifecycle() throws Exception {
|
||||
void dependentShutdownFirstButNotSmartLifecycle() {
|
||||
CopyOnWriteArrayList<Lifecycle> stoppedBeans = new CopyOnWriteArrayList<>();
|
||||
TestSmartLifecycleBean bean1 = TestSmartLifecycleBean.forShutdownTests(1, 200, stoppedBeans);
|
||||
TestLifecycleBean simpleBean = TestLifecycleBean.forShutdownTests(stoppedBeans);
|
||||
|
@ -583,8 +637,7 @@ class DefaultLifecycleProcessorTests {
|
|||
|
||||
|
||||
private static int getPhase(Lifecycle lifecycle) {
|
||||
return (lifecycle instanceof SmartLifecycle) ?
|
||||
((SmartLifecycle) lifecycle).getPhase() : 0;
|
||||
return (lifecycle instanceof SmartLifecycle ? ((SmartLifecycle) lifecycle).getPhase() : 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -596,7 +649,6 @@ class DefaultLifecycleProcessorTests {
|
|||
|
||||
private volatile boolean running;
|
||||
|
||||
|
||||
static TestLifecycleBean forStartupTests(CopyOnWriteArrayList<Lifecycle> startedBeans) {
|
||||
return new TestLifecycleBean(startedBeans, null);
|
||||
}
|
||||
|
@ -734,7 +786,7 @@ class DefaultLifecycleProcessorTests {
|
|||
DummySmartLifecycleBean bean = new DummySmartLifecycleBean();
|
||||
|
||||
@Override
|
||||
public Object getObject() throws Exception {
|
||||
public Object getObject() {
|
||||
return this.bean;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue