玩转 Spring Boot 原理篇(内嵌Tomcat实现原理&优雅停机源码剖析)

Posted 一猿小讲

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了玩转 Spring Boot 原理篇(内嵌Tomcat实现原理&优雅停机源码剖析)相关的知识,希望对你有一定的参考价值。

false)

Type.SERVLET)
ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
     ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
     ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
     ServletWebServerFactoryConfiguration.EmbeddedUndertow.class )
class ServletWebServerFactoryAutoConfiguration 
    // ... ...
static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware 
   // ... ...
         logger.info(          createWebServer();     logger.info(    (Throwable ex)      ApplicationContextException(   WebServer webServer =  ServletContext servletContext = getServletContext(); (webServer == && servletContext ==   ServletWebServerFactory factory = getWebServerFactory();      (servletContext !=      getSelfInitializer().onStartup(servletContext);    (ServletException ex)    ApplicationContextException(    initPropertySources();

WebServer ( Registry.disableRegistry(); Tomcat tomcat = Tomcat(); File baseDir = ( tomcat.setBaseDir(baseDir.getAbsolutePath()); (LifecycleListener listener : tomcat.getServer().addLifecycleListener(listener); Connector connector = Connector( connector.setThrowOnFailure( tomcat.getService().addConnector(connector); customizeConnector(connector); tomcat.setConnector(connector); tomcat.getHost().setAutoDeploy( configureEngine(tomcat.getEngine()); (Connector additionalConnector : tomcat.getService().addConnector(additionalConnector); prepareContext(tomcat.getHost(), initializers); getTomcatWebServer(tomcat);TomcatWebServer TomcatWebServer(tomcat, getPort() >= Assert.notNull(tomcat, GracefulShutdown(tomcat) : initialize(); logger.info(+ getPortsDescription( synchronized ( addInstanceIdToEngineName(); Context context = findContext(); context.addLifecycleListener(( (context. removeServiceConnectors(); ); rethrowDeferredStartupExceptions(); ContextBindings.bindClassLoader(context, context.getNamingToken(), getClass().getClassLoader()); (NamingException ex) startDaemonAwaitThread(); (Exception ex) stopSilently(); destroySilently(); WebServerException( clearResourceCaches(); initLifecycleProcessor(); getLifecycleProcessor().onRefresh(); publishEvent(ContextRefreshedEvent( (!NativeDetector.inNativeImage()) LiveBeansView.registerApplicationContext( startBeans(

  • the target VM, address: code (interrupted signal 2: SIGINT)

    4. 例行回顾

    本文采取 Debug 的方式跟了一下 Spring Boot 源码,梳理了一下 Spring Boot 内嵌 Tomcat 的主线脉略,并对内嵌 Tomcat 启动、关闭进行了深入了解。


    其实回头瞅瞅,Spring Boot 内嵌的 Tomcat 启动、关闭的实现方式,大体可以简化成下面的类图。


  • 内嵌容器启动或关闭时,经过 DefaultLifecycleProcessor 调用一系列方法进行最终是由 WebServerStartStopLifecycle、 WebServerGracefulShutdownLifecycle 来处理。


  • 而WebServerStartStopLifecycle、 WebServerGracefulShutdownLifecycle 持有 webServer 对象,最后调用持有的 X

    xxWebServer 对象的 start、stop 等方法来完成容器的启停操作


  • 本次就分享到这里,这种内嵌 Tomcat 的实现方式,对于轮子的开发或许有点帮助,你们 get 到了没?

    世上没有轻而易举就能获得的成功。所有出众的背后,都有着超乎寻常的努力。真正能够登顶远眺的,都是那些心无旁骛、坚持着往前走的人。再坚持一下,也许你离成功就差那一步。

    一起聊技术、谈业务、喷架构,少走弯路,不踩大坑,会持续输出更多精彩分享,欢迎关注,敬请期待!

    参考资料:

    https://spring.io/

    https://start.spring.io/

    https://spring.io/projects/spring-boot

    https://github.com/spring-projects/spring-boot

    https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/

    https://stackoverflow.com/questions/tagged/spring-boot

    《Spring Boot实战》《深入浅出Spring Boot 2.x》

    《一步一步学Spring Boot:微服务项目实战(第二版)》

    《Spring Boot揭秘:快速构建微服务体系》

    玩转 Spring Boot 原理篇(自动装配源码剖析)

    * Return the AutoConfigurationEntry based on the AnnotationMetadata* of the importing Configuration * annotationMetadata the annotation metadata of the configuration class* the auto-configurations that should be imported*/AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) (!isEnabled(annotationMetadata)) EMPTY_ENTRY; AnnotationAttributes attributes = getAttributes(annotationMetadata); configurations = removeDuplicates(configurations); Set<String> exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = getConfigurationClassFilter().filter(configurations); fireAutoConfigurationImportEvents(configurations, exclusions); AutoConfigurationEntry(configurations, exclusions);

    能够发现getCandidateConfigurations 方法中会通过 SpringFactoriesLoader 类来加载类路径中的 META-INF 目录下的 spring.factories 文件中针对 EnableAutoConfiguration 的注册配置类。

    为了调试方便,在源码中的 process 方法上里加入了打印输出。


    运行后,此时控制台输出如下。

  • AutoConfigurationImportSelector.AutoConfigurationGroup.process() , entries = org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration=smoketest.simple.SampleSimpleApplicationorg.springframework.boot.autoconfigure.aop.AopAutoConfiguration=smoketest.simple.SampleSimpleApplicationorg.springframework.boot.autoconfigure.cache.CacheAutoConfiguration=smoketest.simple.SampleSimpleApplicationorg.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration=smoketest.simple.SampleSimpleApplicationorg.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration=smoketest.simple.SampleSimpleApplicationorg.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration=smoketest.simple.SampleSimpleApplicationorg.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration=smoketest.simple.SampleSimpleApplicationorg.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration=smoketest.simple.SampleSimpleApplicationorg.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration=smoketest.simple.SampleSimpleApplicationorg.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration=smoketest.simple.SampleSimpleApplicationorg.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration=smoketest.simple.SampleSimpleApplicationorg.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration=smoketest.simple.SampleSimpleApplicationorg.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration=smoketest.simple.SampleSimpleApplicationorg.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration=smoketest.simple.SampleSimpleApplication

    2. 例行回顾

    本文采取 Debug 的方式跟了一下 Spring Boot 自动装配的源码,旨在感受一下自动装配的实现方式,其实这种自动装配的思想,在开发轮子时或许能够借鉴一下,会对轮子的扩展带来质的改变。


    为了方便记忆,把 Spring Boot 自动装配繁琐的流程抽象一下。


    另外 Spring Boot 自动装配源码 Debug 主线,感兴趣可以自行跟一下源码。

    一起聊技术、谈业务、喷架构,少走弯路,不踩大坑,会持续输出更多精彩分享,欢迎关注,敬请期待!

    参考资料:

    https://spring.io/

    https://start.spring.io/

    https://spring.io/projects/spring-boot

    https://github.com/spring-projects/spring-boot

    https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/

    https://stackoverflow.com/questions/tagged/spring-boot

    《Spring Boot实战》《深入浅出Spring Boot 2.x》

    《一步一步学Spring Boot:微服务项目实战(第二版)》

    《Spring Boot揭秘:快速构建微服务体系》

    以上是关于玩转 Spring Boot 原理篇(内嵌Tomcat实现原理&优雅停机源码剖析)的主要内容,如果未能解决你的问题,请参考以下文章

    玩转 Spring Boot 原理篇(自动装配源码剖析)

    玩转 Spring Boot 原理篇(核心注解知多少)

    玩转 Spring Boot 原理篇(自动装配前凑之自定义Stater)

    玩转 Spring Boot 集成篇(任务动态管理代码篇)

    Spring Boot内嵌Tomcat原理

    玩转 Spring Boot 入门篇