DockerComposeLifecycleManager Class — spring-boot Architecture
Architecture documentation for the DockerComposeLifecycleManager class in DockerComposeLifecycleManager.java from the spring-boot codebase.
Entity Profile
Relationship Graph
Source Code
core/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/lifecycle/DockerComposeLifecycleManager.java lines 54–184
class DockerComposeLifecycleManager {
private static final Log logger = LogFactory.getLog(DockerComposeLifecycleManager.class);
private static final String IGNORE_LABEL = "org.springframework.boot.ignore";
private final @Nullable File workingDirectory;
private final ApplicationContext applicationContext;
private final @Nullable ClassLoader classLoader;
private final SpringApplicationShutdownHandlers shutdownHandlers;
private final DockerComposeProperties properties;
private final Set<ApplicationListener<?>> eventListeners;
private final DockerComposeSkipCheck skipCheck;
private final ServiceReadinessChecks serviceReadinessChecks;
DockerComposeLifecycleManager(ApplicationContext applicationContext,
SpringApplicationShutdownHandlers shutdownHandlers, DockerComposeProperties properties,
Set<ApplicationListener<?>> eventListeners) {
this(null, applicationContext, shutdownHandlers, properties, eventListeners, new DockerComposeSkipCheck(),
null);
}
DockerComposeLifecycleManager(@Nullable File workingDirectory, ApplicationContext applicationContext,
SpringApplicationShutdownHandlers shutdownHandlers, DockerComposeProperties properties,
Set<ApplicationListener<?>> eventListeners, DockerComposeSkipCheck skipCheck,
@Nullable ServiceReadinessChecks serviceReadinessChecks) {
this.workingDirectory = workingDirectory;
this.applicationContext = applicationContext;
this.classLoader = applicationContext.getClassLoader();
this.shutdownHandlers = shutdownHandlers;
this.properties = properties;
this.eventListeners = eventListeners;
this.skipCheck = skipCheck;
this.serviceReadinessChecks = (serviceReadinessChecks != null) ? serviceReadinessChecks
: new ServiceReadinessChecks(properties.getReadiness());
}
void start() {
if (Boolean.getBoolean(AbstractAotProcessor.AOT_PROCESSING) || AotDetector.useGeneratedArtifacts()) {
logger.trace("Docker Compose support disabled with AOT and native images");
return;
}
if (!this.properties.isEnabled()) {
logger.trace("Docker Compose support not enabled");
return;
}
if (this.skipCheck.shouldSkip(this.classLoader, this.properties.getSkip())) {
logger.trace("Docker Compose support skipped");
return;
}
DockerComposeFile composeFile = getComposeFile();
Set<String> activeProfiles = this.properties.getProfiles().getActive();
List<String> arguments = this.properties.getArguments();
DockerCompose dockerCompose = getDockerCompose(composeFile, activeProfiles, arguments);
if (!dockerCompose.hasDefinedServices()) {
logger.warn(LogMessage.format("No services defined in Docker Compose file %s with active profiles %s",
composeFile, activeProfiles));
return;
}
LifecycleManagement lifecycleManagement = this.properties.getLifecycleManagement();
Start start = this.properties.getStart();
Stop stop = this.properties.getStop();
Wait wait = this.properties.getReadiness().getWait();
List<RunningService> runningServices = dockerCompose.getRunningServices();
if (lifecycleManagement.shouldStart()) {
Skip skip = this.properties.getStart().getSkip();
if (skip.shouldSkip(runningServices)) {
logger.info(skip.getLogMessage());
}
else {
start.getCommand().applyTo(dockerCompose, start.getLogLevel(), start.getArguments());
runningServices = dockerCompose.getRunningServices();
if (wait == Wait.ONLY_IF_STARTED) {
wait = Wait.ALWAYS;
}
if (lifecycleManagement.shouldStop()) {
this.shutdownHandlers
.add(() -> stop.getCommand().applyTo(dockerCompose, stop.getTimeout(), stop.getArguments()));
}
}
}
List<RunningService> relevantServices = new ArrayList<>(runningServices);
relevantServices.removeIf(this::isIgnored);
if (wait == Wait.ALWAYS || wait == null) {
this.serviceReadinessChecks.waitUntilReady(relevantServices);
}
publishEvent(new DockerComposeServicesReadyEvent(this.applicationContext, relevantServices));
}
protected DockerComposeFile getComposeFile() {
DockerComposeFile composeFile = (CollectionUtils.isEmpty(this.properties.getFile()))
? DockerComposeFile.find(this.workingDirectory) : DockerComposeFile.of(this.properties.getFile());
Assert.state(composeFile != null, () -> "No Docker Compose file found in directory '%s'".formatted(
((this.workingDirectory != null) ? this.workingDirectory : new File(".")).toPath().toAbsolutePath()));
if (composeFile.getFiles().size() == 1) {
logger.info(LogMessage.format("Using Docker Compose file %s", composeFile.getFiles().get(0)));
}
else {
logger.info(LogMessage.format("Using Docker Compose files %s", composeFile.toString()));
}
return composeFile;
}
protected DockerCompose getDockerCompose(DockerComposeFile composeFile, Set<String> activeProfiles,
List<String> arguments) {
return DockerCompose.get(composeFile, this.properties.getHost(), activeProfiles, arguments);
}
private boolean isIgnored(RunningService service) {
return service.labels().containsKey(IGNORE_LABEL);
}
/**
* Publish a {@link DockerComposeServicesReadyEvent} directly to the event listeners
* since we cannot call {@link ApplicationContext#publishEvent} this early.
* @param event the event to publish
*/
private void publishEvent(DockerComposeServicesReadyEvent event) {
SimpleApplicationEventMulticaster multicaster = new SimpleApplicationEventMulticaster();
this.eventListeners.forEach(multicaster::addApplicationListener);
multicaster.multicastEvent(event);
}
}
Domain
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free