• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Java > Spring Boot启动过程(五)之Springboot内嵌Tomcat对象的start教程详解

Spring Boot启动过程(五)之Springboot内嵌Tomcat对象的start教程详解

作者:draculav 字体:[增加 减小] 来源:互联网 时间:2017-05-28

draculav 通过本文主要向大家介绍了springboot springmvc,spring和springboot,springboot tomcat,springboot内置tomcat,springboot配置tomcat等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

  标题和Spring Boot启动过程(四)之Spring Boot内嵌Tomcat启动很像,所以特别强调一下,这个是Tomcat对象的。

  从TomcatEmbeddedServletContainer的this.tomcat.start()开始,主要是利用LifecycleBase对这一套容器(engine,host,context及wrapper)进行启动并发布诸如configure_start、before_init、after_start的lifecycleEvent事件给相应的监听器(如果有的话)。进入start,因为此时状态是LifecycleState.NEW,所以会执行init方法:

 public final synchronized void init() throws LifecycleException {
  if(!this.state.equals(LifecycleState.NEW)) {
   this.invalidTransition("before_init");
  }
  try {
   this.setStateInternal(LifecycleState.INITIALIZING, (Object)null, false);
   this.initInternal();
   this.setStateInternal(LifecycleState.INITIALIZED, (Object)null, false);
  } catch (Throwable var2) {
   ExceptionUtils.handleThrowable(var2);
   this.setStateInternal(LifecycleState.FAILED, (Object)null, false);
   throw new LifecycleException(sm.getString("lifecycleBase.initFail", new Object[]{this.toString()}), var2);
  }
 }
</div>

   首先,状态变为LifecycleState.INITIALIZING并发布一个before_init的LifecycleEvent给所有lifecycleListeners:

  这里的super:

  因为上面是server.start调用的start方法,所以虽然方法的代码在LifecycleBase中,但this指的是StandardServer的实例,于是这里的this.initInternal走的是StandardServer的initInternal方法,initInternal首先调用了super.initInternal,这里的super是LifecycleMBeanBase,MBean是用于JMX的能代表管理资源的管理构件,JMX定义了四种管理构件:标准、动态、开放和模型管理构件。每一种管理构件可以根据不同的环境需要进行制定,检查标准管理构件接口和应用设计模式的过程被称为内省(Introspection),动态管理构件提供了更大的灵活性,它可以在运行期暴露自己的管理接口。它的实现是通过实现一个特定的接口DynamicMBean。MBeanFactoryInitializer初始化是在BackgroundPreinitializer的onApplicationEvent。MBean功能相当强大,例如可以提供服务器的远程管理,当然也可以自定义此类功能: 

  onameStringCache = register(new StringCache(), "type=StringCache")注册全局字符串缓存,这里是使用DynamicMBean的方式,注册后StringCache也提供了类似上图的被管理功能,可以远程清楚服务器的字符串缓存等。 下一句globalNamingResources.init()同样的LifecycleBase的init套路,先是setStateInternal更新globalNamingResources的LifecycleState状态为INITIALIZING发布before_init事件,然后NamingResourcesImpl的initInternal,里面依然是之前的super.initInternal(),显示注册ContextResource、ContextEnvironment、ContextResourceLink避免注册时序问题,重复注册没关系;又是一个globalNamingResources的LifecycleBase的setStateInternal方法,更新LifecycleState状态为INITIALIZED发布after_init事件;然后回到StandardServer的initInternal,循环init之前add给server的service:

  又是的LifecycleBase的init,只不过这次是StandardService[Tomcat],更新的LifecycleState状态为INITIALIZING发布before_init事件,StandardService的initInternal,super之后是engine.init,同样engine现在也是初始化阶段,更新状态发布事件,然后进入StandardEngine的initInternal:

 protected void initInternal() throws LifecycleException {
  // Ensure that a Realm is present before any attempt is made to start
  // one. This will create the default NullRealm if necessary.
  getRealm();
  super.initInternal();
 }
</div>

  Realm是关于权限的,具体可以看http://tomcat.apache.org/tomcat-8.0-doc/realm-howto.html;super(ContainerBase).initInternal创建了一个线程池startStopExecutor,这个startStopExecutor之后会接受两种任务StartChild和StopChild用池线程启动和停止子容器,StartStopThreadFactory会在创建线程时将线程设为守护线程,线程名例如:Thread [Tomcat(此处是容器的name)-startStop-1,5,main]。之后setStateInternal更新engine的LifecycleState状态为INITIALIZED发布after_init事件。如果service之前add过Executor,会将这些Executor初始化,如果Executor是JmxEnabled则设置作用范围。mapperListener的初始化没有特殊逻辑,就是先改状态为正在初始化并发布初始化之前的事件,然后注册MBeanServer,再改状态为初始化完成并发布初始化后事件。然后是在同步代码块中初始化Connector,不过之前已经将Connector与Service解绑了,所以这里什么都没做。于是,Service的初始化完成了,更新service的LifecycleState状态为INITIALIZED发布after_init事件。接着Server的初始化也完成了,同样也是更新状态发布事件。回到Server的start(虽然代码在Lifecycle中),setStateInternal(LifecycleState.STARTING_PREP, null, false)更新LifecycleState状态为准备启动,发布before_start事件;startInternal首先发布一个configure_start事件,接着setState(LifecycleState.STARTING)就将状态改为了STARTING同时发布start事件;globalNamingResources.start()更新状态setStateInternal(LifecycleState.STARTING_PREP, null, false)发布before_start事件;globalNamingResources的startInternal方法,发布configure_start事件并setState(LifecycleState.STARTING),globalNamingResources启动完成改状态STARTED发布after_start事件;然后回到server代码中,在同步代码块中启动service:

 // Start our defined Services
  synchronized (servicesLock) {
   for (int i = 0; i < services.length; i++) {
    services[i].start();
   }
  }
</div>

  当前状态的Service会执行setStateInternal(LifecycleState.STARTING_PREP, null, false),然后到StandardService的startInternal方法,setState(LifecycleState.STARTING)不说了,接着是同步代码块中engine.start(),里面是engine状态变更setStateInternal(LifecycleState.STARTING_PREP, null, false),startInternal中super.startInternal执行ContainerBase的对应方法,初始化logger;然后((Lifecycle) realm).start(),start方法里又是一个循环,从NEW到INITIALIZING的状态变化,然后进入RealmBase的initInternal方法

 super.initInternal中MBeanServer,然后this.containerLog = container.getLogger(),此处container是StandardEngine[Tomcat],x509UsernameRetriever = createUsernameRetriever(x509UsernameRetrieverClassName),参考:https://bz.apache.org/bugzilla/show_bug.cgi?id=52500;状态连续更新到INITIALIZED然后STARTING_PREP,发布的什么事件我就不写了,现在还在Realm[Simple]中,接着是RealmBase的startInternal方法,它初始化了credentialHandler = new MessageDigestCredentialHandler()并将状态由改为了STARTING发布start事件,接着又改状态了STARTED事件after_start;然后回到了StandardEngine [Tomcat]中,通过ContainerBase的findChildren方法找到了子容器:

  随后将host的启动,提交给了之前初始化的startStopExecutor:

 for (int i = 0; i < children.length; i++) {
   results.add(startStopExecutor.submit(new StartChild(children[i])));
  }
</div>

  借助Future<Void>获取线程执行的返回值;

  下面就到了执行注册到engine的pipeline中的Value对象了((Lifecycle) pipeline).start(),StandardPipeline整套的状态变化事件发布我就不写了,initInternal方法是空实现,需要说的只有pipeline的startInternal方法,会取第一个Value对象,如果没有会执行basic(StandardEngineValve[Tomcat]实例),最后会将pipeline中的Value对象依次start:    

 Valve current = first;
  if (current == null) {
   current = basic;
  }
  while (current != null) {
   if (current instanceof Lifecycle)
    ((Lifecycle) current).start();
   current = current.getNext();
  }
</div>

  StandardEngineValve的整套start不说了,其中initInternal只有super.initInternal的MBeanServer和初始化containerLog,startInternal就只有改变状态也不说了,出来后是pipeline的状态变化,这个方法状态都是变为STARTING标配也没啥好说的,STARTED然后回到engine,StandardEngine[Tomcat]变状态为STARTING,之后是threadStart(),代码在ContainerBase中,启动了背景线程:

  上面configureEngine中配置的engine.setBackgroundProcessorDelay(this.bac

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • springboot集成spring cache缓存示例代码
  • Spring Boot启动过程(五)之Springboot内嵌Tomcat对象的start教程详解
  • 基于SpringBoot与Mybatis实现SpringMVC Web项目
  • SpringBoot定时任务两种(Spring Schedule 与 Quartz 整合 )实现方法
  • springboot集成spring cache缓存示例代码
  • Spring Boot启动过程(五)之Springboot内嵌Tomcat对象的start教程详解
  • 基于SpringBoot与Mybatis实现SpringMVC Web项目

相关文章

  • 2017-05-28Java中的HashSet详解和使用示例_动力节点Java学院整理
  • 2017-05-28springboot开启声明式事务的方法
  • 2017-05-28Java异常继承结构解析_动力节点Java学院整理
  • 2017-05-28Spring集成Struts与Hibernate入门详解
  • 2017-05-28mybatis自动生成时如何设置不生成Example类详解
  • 2017-05-28javaweb中mysql数据库连接步骤方法及其实例
  • 2017-05-28java实现合并单元格的同时并导出excel示例
  • 2017-05-28Java枚举_动力节点Java学院整理
  • 2017-05-28详解Spring中的FactoryBean
  • 2017-05-28java 汉诺塔详解及实现代码

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Java经典排序算法之归并排序详解
    • java高效打印一个二维数组的实例(不用递归,不用两个for循环)
    • spring boot与redis 实现session共享教程
    • Spring3 整合MyBatis3 配置多数据源动态选择SqlSessionFactory详细教程
    • 基于Spring + Spring MVC + Mybatis 高性能web构建实例详解
    • 图解JAVA中Spring Aop作用
    • SpringBoot(十)之邮件服务
    • Java String对象使用方法详解
    • Java8 新特性Lambda表达式实例详解
    • Java 中的 BufferedWriter 介绍_动力节点Java学院整理

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有