public synchronized void watch(WatchContext context, BuildService.BuildContext buildContext, List<ImageConfiguration> images) throws DockerAccessException,
            MojoExecutionException {

        // Important to be a single threaded scheduler since watch jobs must run serialized
        ScheduledExecutorService executor = null;
        try {
            executor = Executors.newSingleThreadScheduledExecutor();

            for (StartOrderResolver.Resolvable resolvable : runService.getImagesConfigsInOrder(queryService, images)) {
                final ImageConfiguration imageConfig = (ImageConfiguration) resolvable;

                String imageId = queryService.getImageId(imageConfig.getName());
                String containerId = runService.lookupContainer(imageConfig.getName());

                ImageWatcher watcher = new ImageWatcher(imageConfig, context, imageId, containerId);
                long interval = watcher.getInterval();

                WatchMode watchMode = watcher.getWatchMode(imageConfig);
                log.info("Watching " + imageConfig.getName() + (watchMode != null ? " using " + watchMode.getDescription() : ""));

                ArrayList<String> tasks = new ArrayList<>();

                if (imageConfig.getBuildConfiguration() != null) {
                    for (AssemblyConfiguration assemblyConfiguration : imageConfig.getBuildConfiguration().getAllAssemblyConfigurations()) {
                        if (watcher.isCopy()) {
                            String containerBaseDir = assemblyConfiguration.getTargetDir();
                            schedule(executor, createCopyWatchTask(watcher, assemblyConfiguration.getName(), context.getMojoParameters(), containerBaseDir), interval);
                            tasks.add("copying artifacts");
                        }

                        if (watcher.isBuild()) {
                            schedule(executor, createBuildWatchTask(watcher, assemblyConfiguration.getName(), context.getMojoParameters(), watchMode == WatchMode.both, buildContext), interval);
                            tasks.add("rebuilding");
                        }
                    }
                }

                if (watcher.isRun() && watcher.getContainerId() != null) {
                    schedule(executor, createRestartWatchTask(watcher), interval);
                    tasks.add("restarting");
                }

                if (!tasks.isEmpty()) {
                    log.info("%s: Watch for %s", imageConfig.getDescription(), StringUtils.join(tasks.toArray(), " and "));
                }
            }
            log.info("Waiting ...");
            if (!context.isKeepRunning()) {
                runService.addShutdownHookForStoppingContainers(context.isKeepContainer(), context.isRemoveVolumes(), context.isAutoCreateCustomNetworks());
            }
            wait();
        } catch (InterruptedException e) {
            log.warn("Interrupted");
        } finally {
            if (executor != null) {
                executor.shutdownNow();
            }
        }
    }
Watch service for monitoring changes and restarting containers
src/main/java/io/fabric8/maven/docker/service/WatchService.java