当前位置: 首页 > news >正文

做网站就app开发合同模板最新版

做网站就,app开发合同模板最新版,wordpress文字目录,网站右下角悬浮窗口js代码 兼容各浏览器第一篇#xff1a;Tomcat基础篇 lecture#xff1a;邓澎波 一、构建Tomcat源码环境 工欲善其事必先利其器#xff0c;为了学好Tomcat源码#xff0c;我们需要先在本地构建一个Tomcat的运行环境。 1.源码环境下载 源码有两种下载方式#xff1a; 1.1 官网下载 https://… 第一篇Tomcat基础篇 lecture邓澎波 一、构建Tomcat源码环境 工欲善其事必先利其器为了学好Tomcat源码我们需要先在本地构建一个Tomcat的运行环境。 1.源码环境下载 源码有两种下载方式 1.1 官网下载 https://tomcat.apache.org/ 1.2 GitHub下载 当然你也可以通过GitHub来拉取源代码 https://github.com/apache/tomcat 2.Maven环境搭建 2.1 环境准备 打开IEDA导入项目然后在项目中创建一个新的pom.xml文件里面的内容为 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.apache.tomcat/groupIdartifactIdapache-tomcat/artifactIdversion8.5/versiondependenciesdependencygroupIdorg.apache.ant/groupIdartifactIdant/artifactIdversion1.10.4/version/dependencydependencygroupIdwsdl4j/groupIdartifactIdwsdl4j/artifactIdversion1.6.2/version/dependencydependencygroupIdjavax.xml/groupIdartifactIdjaxrpc-api/artifactIdversion1.1/version/dependencydependencygroupIdorg.eclipse.jdt.core.compiler/groupIdartifactIdecj/artifactIdversion4.5.1/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.13/version/dependency/dependenciesbuildfinalNameapache-tomcat/finalNamesourceDirectoryjava/sourceDirectoryresourcesresourcedirectoryjava/directory/resource/resourcespluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion3.8.1/versionconfigurationsource1.8/sourcetarget1.8/targetencodingUTF-8/encoding/configuration/plugin/plugins/build /project然后设置项目为Maven项目选中pom.xml文件鼠标右点。选择 Add as Maven Project . 在右侧出现的Maven菜单中选择编译项目(compile) 2.2 项目启动 编译成功后进入 Bootstrap中启动main方法 出现如下提示说明启动成功只是中文乱码了 2.3 解决中文乱码问题 中文乱码问题的解决方案修改两处地方即可 1.修改org.apache.jasper.compiler.Localizer#getMessage(java.lang.String)方法 public static String getMessage(String errCode) {String errMsg errCode;try {if (bundle ! null) {errMsg bundle.getString(errCode);}} catch (MissingResourceException e) {}try{errMsg new String(errMsg.getBytes(ISO-8859-1),UTF-8);}catch (UnsupportedEncodingException e){e.printStackTrace();}return errMsg;}2.修改org.apache.tomcat.util.res.StringManager#getString(java.lang.String) 重启服务 启动正常但是访问的时候出现了问题 2.4 解决不支持JSP的问题 启动成功后在访问首页的时候出现了500错误而且提示 无法为JSP编译类。 原因是无法编译jsp。解决也很简单按照下面步骤操作即可 上面的报错解决方式可以在org.apache.catalina.startup.ContextConfig类中的configureStart方法中添加一下JSP解析器初始化即可 context.addServletContainerInitializer(new JasperInitializer(), null);重启服务访问搞定 到此Tomcat的源码环境我们就已经准备好了接下来就可以开始我们的Tomcat源码之旅了!!! 二、Tomcat源码结构介绍 在分析Tomcat源码之前我们先来看下Tomcat源码的结构组成这样会更加的有利于我们更好的来分析源码。 1.项目源码结构 我们先从源码结构开始。Tomcat 服务器相关的代码在 java 文件夹下面后面我们在进入这个文件夹去分析 之前如何手动在Tomcat中部署过项目的话这块应该会比较清楚点。 2.Tomcat源码结构 Tomcat 源码位于 java 文件夹下面。这个java文件夹中的每个包的作用我们简单的来介绍下后面在分析核心源码的时候会重点讲解。 我们可以看到在java目录下分为了两个结构一个是javax另一个是org.apache这两个包 2.1 javax 在javax中保存的是新的JavaEE规范。可以具体来看看每个目录的作用。 模块作用说明annotationannotation 这个模块的作用是定义了一些公用的注解避免在不同的规范中定义相同的注解。ejbejb是个古老的传说我们不管el在jsp中可以使用EL表达式这么模块解析EL表达式的mail和邮件相关的规范persistence持久化相关的security和安全相关的内容servlet这个指定的是Servlet的开发规范Tomcat本质上就是一个实现了Servlet规范的一个容器Servlet定义了服务端处理Http请求和响应的方式(规范)websocket定义了使用 websocket 协议的服务端和客户端 APIxml.ws定义了基于 SOAP 协议的 xml 方式的 web 服务 2.2 org.apache org.apache这个包是Tomcat的源码包也是针对上面的JavaEE规范的部分实现Tomcat的本质就是对JavaEE的某些规范的实现合集首先肯定实现了Servlet规范 模块作用catalinacatalina是Tomcat的核心模块里面完整的实现了Servlet规范Tomcat启动的主方法也在里面后面我们分析的重点。coyotetomcat 的核心代码负责将网络请求转化后和 Catalina 进行通信。el这个是上面javax中的el规范的实现jasper主要负责把jsp代码转换为java代码。juli日志相关的工具naming命名空间相关的内容tomcat各种辅助工具包括 websocket 的实现。 3.Tomcat模块设计 连接器的作用 连接器功能· 监听网络端口。接受网络连接请求。根据具体应用层协议http/ajp解析字节流生成统一的Tomcat Request对象。将Tomcat Request对象转成标准的ServletRequest。调用Servlet容器得到ServletResponse。将ServletResponse转成Tomcat Response对象。将Tomcat Response转成网络字节流。将响应字节流写回给浏览器。 三、Tomcat的架构设计 1.Servlet规范 1.1 Servlet作用讲解 Servlet是JavaEE规范中的一种主要是为了扩展Java作为Web服务的功能统一定义了对应的接口比如Servlet接口HttpRequest接口HttpResponse接口Filter接口。然后由具体的服务厂商来实现这些接口功能比如Tomcatjetty等。 ems;在规范里面并不会有具体的实现。可以自行看下源码而在Servlet规范中规定了一个http请求到来的执行处理流程:对应的服务器容器会接收到对应的Http请求然后解析该请求然后创建对应的Servlet实例调用对应init方法来完成初始化把请求的相关信息封装为HttpServletRequest对象来调用Servlet的service方法来处理请求然后通过HttpServletResponse封装响应的信息交给容器响应给客户端。 1.2 Servlet核心API 我们再来回顾下Servlet中的核心API这块对我们更好的掌握Tomcat的内容还是非常有帮助的。 API描述ServletConfig获取servlet初始化参数和servletContext对象。ServletContext在整个Web应用的动态资源之间共享数据。ServletRequest封装Http请求信息在请求时创建。ServletResponse封装Http响应信息在请求时创建。 ServletConfig 容器在初始化servlet时为该servlet创建一个servletConfig对象并将这个对象通过init()方法来传递并保存在此Servlet对象中。核心作用 获取初始化信息;获取ServletContext对象。 ServletContext 一个项目只有一个ServletContext对象可以在多个Servlet中来获取这个对象使用它可以给多个Servlet传递数据该对象在Tomcat启动时就创建在Tomcat关闭时才会销毁作用是在整个Web应用的动态资源之间共享数据。 在实际的Servlet开发中我们会实现HttpServlet接口在该接口中会实现GenericServlet,而在GenericServlet会实现ServiceConfig接口从而可以获取ServletContext容器对象 所以在Servlet中我们可以很容易的获取到ServletContext对象从而完成对应的操作。 public class ServletTwoImpl extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType(text/html;charsetutf-8);// 1、参数传递ServletContext servletContext this.getServletContext() ;String value String.valueOf(servletContext.getAttribute(name)) ;System.out.println(valuevalue);// 2、获取初始化参数String userName servletContext.getInitParameter(user-name) ;System.out.println(userNameuserName);// 3、获取应用信息String servletContextName servletContext.getServletContextName() ;System.out.println(servletContextNameservletContextName);// 4、获取路径String pathOne servletContext.getRealPath(/) ;String pathTwo servletContext.getRealPath(/WEB-INF/) ;System.out.println(pathOnepathOne;pathTwopathTwo);response.getWriter().print(执行doGet; valuevalue);} } 1.3 ServletRequest HttpServletRequest接口继承ServletRequest接口用于封装请求信息该对象在用户每次请求servlet时创建并传入servlet的service()方法在该方法中传入的servletRequest将会被强制转化为HttpservletRequest 对象来进行HTTP请求信息的处理。核心作用 获取请求报文信息;获取网络连接信息;获取请求域属性信息。 1.4 ServletResponse HttpServletResponse继承自ServletResponse封装了Http响应信息。客户端每个请求服务器都会创建一个response对象并传入给Servlet.service()方法。核心作用 设置响应头信息;发送状态码;设置响应正文;重定向 2.Tomcat的设计 通过上面Servlet规范的介绍其实我们发下我们要实现Servlet规范的话很重要的就得提供一个服务容器来获取请求解析封装数据并调用Servlet实例相关的方法。也就是如下图中的部分 这块的内容其实就是Tomcat具体的我们来看看。 2.1 什么是Tomcat Tomcat是一个容器用于承载Servlet那么我们说Tomcat就是一个实现了部分J2EE规范的服务器。J2 EE和Jakarta EEEclipse基金会这两是啥用于Tomcat10以后都是Jakarta EE而9之前就是J2EE. 2.2 Tomcat的架构结构 我们通过上面的分析知道Tomcat是一个Servlet规范的实现要接收请求和响应请求那么具体是如何实现的呢这块我们可以通过conf下的server.xml得出对应的结论。 server.xml是Tomcat中最重要的配置文件server.xml 的每一个元素都对应了Tomcat 中的一个组件 通过对xml文件中元素的配置可以实现对Tomcat中各个组件的控制。因此学习server.xml文件的配置对于了解和使用Tomcat至关重要. 官方文档https://tomcat.apache.org/tomcat-8.5-doc/config/server.html ?xml version1.0 encodingUTF-8?Server port8005 shutdownSHUTDOWNService nameCatalinaExecutor nametomcatThreadPool namePrefixcatalina-exec-maxThreads150 minSpareThreads4/Connector port8080 protocolHTTP/1.1connectionTimeout20000redirectPort8443 /Connector executortomcatThreadPoolport8080 protocolHTTP/1.1connectionTimeout20000redirectPort8443 /Engine nameCatalina defaultHostlocalhostRealm classNameorg.apache.catalina.realm.LockOutRealm!-- This Realm uses the UserDatabase configured in the global JNDIresources under the key UserDatabase. Any editsthat are performed against this UserDatabase are immediatelyavailable for use by the Realm. --Realm classNameorg.apache.catalina.realm.UserDatabaseRealmresourceNameUserDatabase//RealmHost namelocalhost appBasewebappsunpackWARstrue autoDeploytrueValve classNameorg.apache.catalina.valves.AccessLogValve directorylogsprefixlocalhost_access_log suffix.txtpattern%h %l %u %t %r %s %b //Host/Engine/Service /Server 极简模式 ServerServiceConnector /Connector /EngineHostContext /!-- 现在常常使用自动部署不推荐配置Context元素Context小节有详细说明 --/Host/Engine/Service /Server梳理出的结构 对应的每个组件的作用。 2.3 组件分类 官网其实对上面的组件也做了分类: 顶级元素: Server是整个配置文件的根元素Service:代表一个Engine元素以及一组与之相连的Connector元素 连接器 代表了外部客户端发送请求到特定Service的接口同时也是外部客户端从特定Service接收响应的接口。 容器 容器的作用是处理Connector接收进来的请求并产生对应的响应EngineHost和Context都是容器他们不是平行关系而是父子关系。 每个组件的作用 Engine:可以处理所有请求Host:可以处理发向一个特定虚拟主机的所有请求Context:可以处理一个特定Web应用的所有请求 核心组件的串联关系 当客户端请求发送过来后其实是通过这些组件相互之间配合完成了对应的操作。 Server元素在最顶层代表整个Tomcat容器一个Server元素中可以有一个或多个Service元素Service在Connector和Engine外面包了一层把它们组装在一起对外提供服务。一个Service可以包含多个Connector但是只能包含一个EngineConnector接收请求Engine处理请求。Engine、Host和Context都是容器且Engine包含HostHost包含Context。每个Host组件代表Engine中的一个虚拟主机每个Context组件代表在特定Host上运行的一个Web应用. 整体Tomcat的运行架构图 四、Tomcat生命周期 在上篇文章中我们看到了Tomcat架构中的核心组件而且各个组件都有各自的作用各司其职而且相互之间也有对应的父子关系那么这些对象的创建调用销毁等操作是怎么处理呢 也就是在Tomcat中的组件的对象生命周期是怎么管理的呢针对这个问题在Tomcat中设计了Lifecycle接口来统一管理Tomcat中的核心组件的生命周期所以本文我们就系统的来介绍下Lifecycle接口的设计 1、LifeCycle接口设计 为了统一管理Tomcat中的核心组件的生命周期而专门设计了LifeCycle接口来统一管理我们来看看在LifeCycle接口中声明了哪些内容。 1.1 生命周期的方法 在LifeCycle中声明了和生命周期相关的方法包括init(),start(),stop(),destory()等方法。 在声明的方法执行的过程中会涉及到对应的状态的转换在LifeCycle接口的头部文档中很清楚的说了。 1.2 相关的状态处理 通过上图我们可以很清楚的看到相关的方法执行会涉及到的相关状态的转换比如init()会从New这个状态开始然后会进入 INITIALIZING 和 INITIALIZED 等。因为这块涉及到了对应的状态转换在Lifecycle中声明了相关的状态和事件的生命周期字符串。 public static final String BEFORE_START_EVENT before_start;public static final String AFTER_START_EVENT after_start;public static final String STOP_EVENT stop;public static final String BEFORE_STOP_EVENT before_stop;public static final String AFTER_STOP_EVENT after_stop;public static final String AFTER_DESTROY_EVENT after_destroy;public static final String BEFORE_DESTROY_EVENT before_destroy;/*** The LifecycleEvent type for the periodic event.* 周期性事件后台线程定时执行一些事情比如热部署、热替换*/public static final String PERIODIC_EVENT periodic;public static final String CONFIGURE_START_EVENT configure_start;public static final String CONFIGURE_STOP_EVENT configure_stop;在LifecycleState中建立了对应关系 针对特定的事件就会有相关的监听器来监听处理。在Lifecycle中定义了相关的处理方法。 public void addLifecycleListener(LifecycleListener listener);public LifecycleListener[] findLifecycleListeners();public void removeLifecycleListener(LifecycleListener listener);通过方法名称我们就能很清楚该方法的相关作用就不过程介绍了。然后来看下对应的监听器和事件接口的对应设计。 2.监听器和事件的设计 接下来看下LifecycleListener的设计。其实代码非常简单。 public interface LifecycleListener {/*** Acknowledge the occurrence of the specified event.* 触发监听器后要执行逻辑的方法* param event LifecycleEvent that has occurred*/public void lifecycleEvent(LifecycleEvent event);}然后来看下事件的接口 public final class LifecycleEvent extends EventObject {private static final long serialVersionUID 1L;/*** Construct a new LifecycleEvent with the specified parameters.** param lifecycle Component on which this event occurred* param type Event type (required)* param data Event data (if any)*/public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {super(lifecycle); // 向上转型可接受一切实现了生命周期的组件this.type type;this.data data;}/*** The event data associated with this event.* 携带的额外的数据传递给监听器的数据*/private final Object data;/*** The event type this instance represents.* 事件类型*/private final String type;/*** return the event data of this event.*/public Object getData() {return data;}/*** return the Lifecycle on which this event occurred.*/public Lifecycle getLifecycle() {return (Lifecycle) getSource();}/*** return the event type of this event.*/public String getType() {return this.type;} }也是非常简单不过多的赘述。 3.LifecycleBase 通过上面的介绍我们可以看到在Tomcat中设计了Lifecycle和LifecycleListener和LifecycleEvent来管理核心组件的生命周期那么我们就需要让每一个组件都实现相关的接口。这时你会发现交给子类的工作量其实是比较大的不光要完成各个组件的核心功能还得实现生命周期的相关处理耦合性很强这时在Tomcat中给我们提供了一个LifecycleBase的抽象类帮助我们实现了很多和具体业务无关的处理来简化了具体组件的业务。 3.1 事件处理 在上面的接口设计中对于监听对应的事件处理是没有实现的在LifecycleBase把这块很好的实现了我们来看下。首先定义了一个容器来存储所有的监听器 // 存储了所有的实现了LifecycleListener接口的监听器 private final ListLifecycleListener lifecycleListeners new CopyOnWriteArrayList();同时提供了触发监听的相关的方法绑定了对应的事件。 /*** Allow sub classes to fire {link Lifecycle} events.* 监听器触发相关的事件* param type Event type 事件类型* param data Data associated with event.*/protected void fireLifecycleEvent(String type, Object data) {LifecycleEvent event new LifecycleEvent(this, type, data);for (LifecycleListener listener : lifecycleListeners) {listener.lifecycleEvent(event);}}已经针对Listener相关的处理方法 // 添加监听器Overridepublic void addLifecycleListener(LifecycleListener listener) {lifecycleListeners.add(listener);}// 查找所有的监听并转换为了数组类型Overridepublic LifecycleListener[] findLifecycleListeners() {return lifecycleListeners.toArray(new LifecycleListener[0]);}// 移除某个监听器Overridepublic void removeLifecycleListener(LifecycleListener listener) {lifecycleListeners.remove(listener);} 3.2 生命周期方法 在LifecycleBase中最核心的还是实现了Lifecycle中的生命周期方法以init方法为例我们来看。 /*** 实现了 Lifecycle 中定义的init方法* 该方法和对应的组件的状态产生的关联* throws LifecycleException*/Overridepublic final synchronized void init() throws LifecycleException {if (!state.equals(LifecycleState.NEW)) {// 无效的操作 只有状态为 New 的才能调用init方法进入初始化invalidTransition(Lifecycle.BEFORE_INIT_EVENT);}try {// 设置状态为初始化进行中....同步在方法中会触发对应的事件setStateInternal(LifecycleState.INITIALIZING, null, false);initInternal(); // 交给子类具体的实现 初始化操作// 更新状态为初始化完成 同步在方法中会触发对应的事件setStateInternal(LifecycleState.INITIALIZED, null, false);} catch (Throwable t) {handleSubClassException(t, lifecycleBase.initFail, toString());}}源码解析 我们看到首先会判断当前对象的state状态是否为NEW,因为init方法只能在NEW状态下才能开始初始化如果1条件满足则会更新state的状态为 INITIALIZED 同时会触发这个事件然后initInternale()方法会交给子类具体去实现等待子类处理完成后会把状态更新为 INITIALIZED。 我们可以进入setStateInternal方法查看最后的关键代码 // ....this.state state; // 更新状态// 根据状态和事件的绑定关系获取对应的事件String lifecycleEvent state.getLifecycleEvent();if (lifecycleEvent ! null) {// 发布对应的事件fireLifecycleEvent(lifecycleEvent, data);}可以看到和对应的事件关联起来了。init方法的逻辑弄清楚后你会发现start方法stop方法destory方法的处理逻辑都是差不多的可自行观看。而对应的 initInternal()方法的逻辑我们需要在 Server Service Engine Connector等核心组件中再看这个我们会结合Tomcat的启动流程来带领大家一起查看。下一篇给大家介绍。 五、Tomcat的启动核心流程 前面给大家介绍了Tomcat中的生命周期的设计掌握了这块对于我们分析Tomcat的核心流程是非常有帮助的也就是我们需要创建相关的核心组件比如ServerService肯定都绕不开生命周期的方法。 1.启动的入口 你可以通过脚本来启动Tomcat服务(startup.bat),但如果你看过脚本的命令你会发现最终调用的还是Bootstrap中的main方法所以我们需要从main方法来开始 然后我们去看main方法中的代码我们需要重点关注的方法有三个 bootstrap.init()方法load()方法start()方法 也就是在这三个方法中会完成Tomcat的核心操作。 2.init方法 我们来看下init方法中的代码非核心的我们直接去掉 public void init() throws Exception {// 创建相关的类加载器initClassLoaders();// 省略部分代码...// 通过反射创建了 Catalina 类对象Class? startupClass catalinaLoader.loadClass(org.apache.catalina.startup.Catalina);// 创建了 Catalina 实例Object startupInstance startupClass.getConstructor().newInstance();// 省略部分代码...String methodName setParentClassLoader;Class? paramTypes[] new Class[1];paramTypes[0] Class.forName(java.lang.ClassLoader);Object paramValues[] new Object[1];paramValues[0] sharedLoader;// 把 sharedLoader 设置为了 commonLoader的父加载器Method method startupInstance.getClass().getMethod(methodName, paramTypes);method.invoke(startupInstance, paramValues);// Catalina 实例 赋值给了 catalinaDaemoncatalinaDaemon startupInstance;}首先是调用了initClassLoaders()方法这个方法会完成对应的ClassLoader的创建这个比较重要后面专门写一篇文章来介绍。通过反射的方式创建了Catalina的类对象并通过反射创建了Catalina的实例设置了类加载器的父子关系用过成员变量catalinaDaemon记录了我们创建的Catalina实例 这个是通过bootstrap.init()方法我们可以获取到的有用的信息。然后我们继续往下面看。 3.load方法 然后我们来看下load方法做了什么事情代码如下 private void load(String[] arguments) throws Exception {// Call the load() methodString methodName load; // load方法的名称Object param[];Class? paramTypes[];if (argumentsnull || arguments.length0) {paramTypes null;param null;} else {paramTypes new Class[1];paramTypes[0] arguments.getClass();param new Object[1];param[0] arguments;}// catalinaDaemon 就是在 init中创建的 Catalina 对象Method method catalinaDaemon.getClass().getMethod(methodName, paramTypes);if (log.isDebugEnabled()) {log.debug(Calling startup class method);}// 会执行 Catalina的load方法method.invoke(catalinaDaemon, param);} 上面的代码非常简单通过注释我们也可以看出该方法的作用是调用 Catalina的load方法。所以我们还需要加入到Catalina的load方法中来查看代码同样比较长只留下关键代码 public void load() {if (loaded) {return; // 只能被加载一次}loaded true;initDirs(); // 废弃的方法// Before digester - it may be neededinitNaming(); // 和JNDI 相关的内容 忽略// Create and execute our Digester// 创建并且执行我们的 Digester 对象 Server.xmlDigester digester createStartDigester();// 省略掉了 Digester文件处理的代码getServer().setCatalina(this); // Server对象绑定 Catalina对象getServer().setCatalinaHome(Bootstrap.getCatalinaHomeFile());getServer().setCatalinaBase(Bootstrap.getCatalinaBaseFile());// Stream redirectioninitStreams();// 省略掉了部分代码...getServer().init(); // 完成 Server Service Engine Connector等组件的init操作}把上面的代码简化后我们发现这个Load方法其实也是蛮简单的就做了两件事。 通过Apache下的Digester组件完成了Server.xml文件的解析通过getServer().init() 方法完成了Server,Service,Engin,Connector等核心组件的初始化操作这块和前面的LifecycleBase呼应起来了。 如果生命周期的内容不清楚请看上一篇文章的介绍。 4.start方法 最后我们来看下start方法的代码。 public void start() throws Exception {if (catalinaDaemon null) {init(); // 如果 catalinaDaemon 为空 初始化操作}// 获取的是 Catalina 中的 start方法Method method catalinaDaemon.getClass().getMethod(start, (Class [])null);// 执行 Catalina 的start方法method.invoke(catalinaDaemon, (Object [])null);}上面的代码逻辑也很清楚就是通过反射的方式调用了Catalina对象的start方法。所以进入Catalina的start方法中查看。 public void start() {if (getServer() null) {load(); // 如果Server 为空 重新 init 相关的组件}if (getServer() null) {log.fatal(Cannot start server. Server instance is not configured.);return;}// Start the new server 关键方法---启动Servertry {getServer().start();} catch (LifecycleException e) {// 省略...}// 省略...// Register shutdown hook 注册关闭的钩子if (useShutdownHook) {// 省略...}if (await) {await();stop();}}通过上面的代码我们可以发现核心的代码还是getServer.start()方法也就是通过Server对象来嵌套的调用相关注解的start方法。 5.核心流程的总结 我们可以通过下图来总结下Tomcat启动的核心流程 从图中我们可以看到Bootstrap其实没有做什么核心的事情主要还是Catalina来完成的。
http://www.dnsts.com.cn/news/18559.html

相关文章:

  • 深圳手机端网站建设专业wordpress 迁移 步骤
  • mysql开发网站开发国内重大新闻2022
  • 汕头网站建设推广平台西安网站设计试听
  • 一等一网站建设网页游戏平台系统
  • 网站建设工作进度计划表做网站维护费是怎么算的
  • 网站建设皿金手指排名企查查企业信息查询系统官网
  • 网站通信管理部门备案wordpress导航主题下载
  • 多种成都网站建设如何创建网站快捷方式到桌面
  • 建设部网站 专业评估安阳新闻最新消息
  • 用jsp做网站主界面做网站如何挑选服务器
  • 快递物流公司网站模板采购网上商城
  • 外国做ppt的网站宁夏住房和城乡建设部网站
  • 建设厅培训中心网站网站网页压缩
  • 尧都区建设厅官方网站电商网站开发用什么语言
  • 游戏 网站 模板在线永久免费的服务器有哪些
  • 网站建设策划书结束语在线设计logo图案免费
  • cms建站程序河北seo推广
  • 免费网站建站教程中国企业500强怎么评的
  • 地方资讯网站源码重庆营销网站建设公司排名
  • 自己做的网站如何让qq登录连云港网站建设优化
  • 云主机 网站吗沧州建设厅网站
  • 做视频图片博客网站有哪些网站图片展示代码
  • 云南哪有网站建设报价的桂林市区到阳朔有多远
  • 昌邑网站建设公司做网站一年赚80亿
  • 网站模板 使用阿里云搭建公司网站
  • 怎么做qq靓号网站四川建设网上班时间
  • 做网站的外包能学到什么推广赚钱软件
  • 注册了域名怎样做网站网站分析报告范文2000
  • 建设网站的方案中铁建设集团门户网登录网站
  • 做问答网站要多少钱湖南省郴州市十大旅游景点排行榜