11/*
2- * Copyright 2015-2023 the original author or authors.
2+ * Copyright 2015-2025 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
3131import java .util .Map .Entry ;
3232import java .util .Properties ;
3333import java .util .Set ;
34+ import java .util .concurrent .atomic .AtomicBoolean ;
3435import java .util .concurrent .locks .ReentrantLock ;
3536import java .util .stream .Stream ;
3637
4748import org .springframework .context .ApplicationEvent ;
4849import org .springframework .context .ApplicationListener ;
4950import org .springframework .context .ConfigurableApplicationContext ;
51+ import org .springframework .context .SmartLifecycle ;
5052import org .springframework .context .annotation .AnnotationConfigApplicationContext ;
5153import org .springframework .context .support .GenericApplicationContext ;
5254import org .springframework .core .convert .converter .Converter ;
7880 * @author Byungjun You
7981 * @author Omer Celik
8082 */
81- public class DefaultBinderFactory implements BinderFactory , DisposableBean , ApplicationContextAware {
83+ public class DefaultBinderFactory implements BinderFactory , DisposableBean , ApplicationContextAware , SmartLifecycle {
8284
8385 protected final Log logger = LogFactory .getLog (getClass ());
8486
@@ -94,6 +96,8 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl
9496
9597 private final BinderCustomizer binderCustomizer ;
9698
99+ private final AtomicBoolean running = new AtomicBoolean ();
100+
97101 private volatile ConfigurableApplicationContext context ;
98102
99103 private Collection <Listener > listeners ;
@@ -144,6 +148,27 @@ public void destroy() {
144148 this .defaultBinderForBindingTargetType .clear ();
145149 }
146150
151+ @ Override
152+ public void start () {
153+ // This is essentially used when CRaC checkpoint is restored
154+ if (this .running .compareAndSet (false , true )) {
155+ this .binderInstanceCache .values ().stream ().map (Entry ::getValue ).forEach (ConfigurableApplicationContext ::start );
156+ }
157+ }
158+
159+ @ Override
160+ public void stop () {
161+ // Makes sense for CRaC checkpoint
162+ if (this .running .compareAndSet (true , false )) {
163+ this .binderInstanceCache .values ().stream ().map (Entry ::getValue ).forEach (ConfigurableApplicationContext ::stop );
164+ }
165+ }
166+
167+ @ Override
168+ public boolean isRunning () {
169+ return this .running .get ();
170+ }
171+
147172 @ SuppressWarnings ({ "unchecked" , "rawtypes" })
148173 @ Override
149174 public <T > Binder <T , ?, ?> getBinder (String name , Class <? extends T > bindingTargetType ) {
0 commit comments