# spring-context 7.0.10 sources: DefaultLifecycleProcessor, the object that starts and stops SmartLifecycle beans --- doStart: start() is called only when isRunning() is false --- private void doStart(Map lifecycleBeans, String beanName, boolean autoStartupOnly, @Nullable List> futures) { Lifecycle bean = lifecycleBeans.remove(beanName); if (bean != null && bean != this) { String[] dependenciesForBean = getBeanFactory().getDependenciesForBean(beanName); for (String dependency : dependenciesForBean) { doStart(lifecycleBeans, dependency, autoStartupOnly, futures); } if (!bean.isRunning() && (!autoStartupOnly || toBeStarted(beanName, bean))) { if (futures != null) { futures.add(CompletableFuture.runAsync(() -> doStart(beanName, bean), getBootstrapExecutor())); } else { doStart(beanName, bean); } } } } --- doStop: stop() is called only when isRunning() is true --- private void doStop(Map lifecycleBeans, final String beanName, boolean pauseableOnly, final CountDownLatch latch, final Set countDownBeanNames) { Lifecycle bean = lifecycleBeans.remove(beanName); if (bean != null) { String[] dependentBeans = getBeanFactory().getDependentBeans(beanName); for (String dependentBean : dependentBeans) { doStop(lifecycleBeans, dependentBean, pauseableOnly, latch, countDownBeanNames); } try { if (bean.isRunning()) { Set stoppedBeans = this.stoppedBeans; if (stoppedBeans != null) { stoppedBeans.add(beanName); } if (bean instanceof SmartLifecycle smartLifecycle) { if (!pauseableOnly || smartLifecycle.isPauseable()) { if (logger.isTraceEnabled()) { logger.trace("Asking bean '" + beanName + "' of type [" + bean.getClass().getName() + "] to stop"); } countDownBeanNames.add(beanName); smartLifecycle.stop(() -> { latch.countDown(); countDownBeanNames.remove(beanName); if (logger.isDebugEnabled()) { logger.debug("Bean '" + beanName + "' completed its stop procedure"); } }); } else { // Don't wait for beans that aren't pauseable... latch.countDown(); } } else if (!pauseableOnly) { if (logger.isTraceEnabled()) { logger.trace("Stopping bean '" + beanName + "' of type [" + bean.getClass().getName() + "]"); } bean.stop(); if (logger.isDebugEnabled()) { logger.debug("Successfully stopped bean '" + beanName + "'"); } } } else if (bean instanceof SmartLifecycle) { // Don't wait for beans that aren't running... latch.countDown(); } } catch (Throwable ex) { if (logger.isWarnEnabled()) { logger.warn("Failed to stop bean '" + beanName + "'", ex); } if (bean instanceof SmartLifecycle) { latch.countDown(); } } } } --- isAutoStartupCandidate / toBeStarted: what isAutoStartup() decides --- private boolean isAutoStartupCandidate(String beanName, Lifecycle bean) { Set stoppedBeans = this.stoppedBeans; return (stoppedBeans != null ? stoppedBeans.contains(beanName) : (bean instanceof SmartLifecycle smartLifecycle && smartLifecycle.isAutoStartup())); } private boolean toBeStarted(String beanName, Lifecycle bean) { Set stoppedBeans = this.stoppedBeans; return (stoppedBeans != null ? stoppedBeans.contains(beanName) : (!(bean instanceof SmartLifecycle smartLifecycle) || smartLifecycle.isAutoStartup())); }