网站外链建设常用字,it运维外包服务,网站怎样快速排名,wordpress 统计接上一篇#xff0c;说到XmlConfiguration ,XmlConfiguration 利用自己实现的 IOC 组装 Server 的全过程如下图所示#xff1a; 这里可以看到 3 个关键的配置文件#xff0c; jetty.xml 、 jetty-deploy.xml 、以及 contexts/xxx.xml l Jetty.xml 文件中定义了… 接上一篇说到XmlConfiguration ,XmlConfiguration 利用自己实现的 IOC 组装 Server 的全过程如下图所示 这里可以看到 3 个关键的配置文件 jetty.xml 、 jetty-deploy.xml 、以及 contexts/xxx.xml l Jetty.xml 文件中定义了入口类 Server, 以及其所需要的线程池、 Connector 、 Handler 。 l Jetty-deploy.xml 中则定义了部署 web 应用用到部署工具在其中指定了部署 web 应用的两种方式类似于 tomcat, 如果采用 webappProvider 则表示将 web 应用放在 webapp 下即可生效如果采用 ContextProvider 则需要定义 Contexts 目录所在位置只要在该目录下放置任何应用的 context 配置文件就可以生效。 l Xxx.xml 这是一个用户自定义文件表示采用 ContextProvider 时在其中定义一个 WebAppContext 的 handler, 它指定了我们应用所在的位置便于加载。 XmlConfiguration 解析装配完毕之后就开始启动服务 Jetty 的启动是从 Server 开始的我们来看一下服务器真正的启动过程。 从上图中我们能大概看出服务器启动过程先是由用户设置好需要的核心组件然后调用 Server.start() 开始启动服务其中会首先启动 handler 处理器之后启动用户自定义组件这个自定义组件需要实现 LifeCyle 接口最后才启动 Connector 接受请求。可以想到关闭过程恰好是反过来首先关闭接受请求的 connector 然后再关闭用户自定义组件最后关闭 handler. 我们再来详细看一下 Server 源代码的核心实现过程当调用 start 方法时其实是调用其祖先类 AbstractLifeCycle 中方法该方法在这里有一个模板实现如下 public final void start() throws Exception { synchronized (_lock) { try { if (_state __STARTED || _state __STARTING) return; setStarting(); doStart(); setStarted(); } catch (Exception e) { setFailed(e); throw e; } catch (Error e) { setFailed(e); throw e; } } } Connector 启动过程 看下 Connector 的详细启动过程 ( 以 NIO 为例 ) NIOConnector 启动过程中先创建了多个 SelectSet 对象每个 SelectSet 负责一个 NIO 的 Selector 专门用于监听 read 事件 ( 这里利用的多线程 Reactor 模式 http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf ) 当然这里仅仅是创建了对象并没有启动后面会提到。 SelectorManager 然后再调用 open 创建了一个 blocking 的阻塞 channel 专门用于接受用户的新连接我们看下 public void open() throws IOException { synchronized(this) { if (_acceptChannel null) { // Create a new server socket _acceptChannel ServerSocketChannel.open(); // Set to blocking mode _acceptChannel.configureBlocking(true); // Bind the server socket to the local host and port _acceptChannel.socket().setReuseAddress(getReuseAddress()); InetSocketAddress addr getHost()null?new InetSocketAddress(getPort()):new InetSocketAddress(getHost(),getPort()); _acceptChannel.socket().bind(addr,getAcceptQueueSize()); _localPort_acceptChannel.socket().getLocalPort(); if (_localPort0) throw new IOException(Server channel not bound); } } } 随后从线程池中分配了 N 个 ( 可以在配置文件中配置 ) 线程用于启动 SelectSet 监听 read 事件。 synchronized (this) { _acceptorThread new Thread[getAcceptors()]; for (int i 0; i _acceptorThread.length; i) _threadPool.dispatch(new Acceptor(i)); if (_threadPool.isLowOnThreads()) Log.warn(insufficient threads configured for {},this); } 最后再分配 1 个线程用于 accept 用户的新连接新连接来之后会将其设置为 nonblocking 模式之后就将其 Register 给某个 SelectSet 去监听 read 事件然后又返回来继续监听新连接 _manager.dispatch(new Runnable() { public void run() { final ServerSocketChannel server_acceptChannel; while (isRunning() _acceptChannelserver server.isOpen()) { try { SocketChannel channel server.accept(); channel.configureBlocking(false); Socket socket channel.socket(); configure(socket); _manager.register(channel); } catch(IOException e) { Log.ignore(e); } } } }); Handler 启动过程 Jetty 将所有的真正处理请求的动作都抽象成了 Handler 因此做事情的组件都是实现了这个接口的包括上图所示的 WebAppContext 等等需要做什么样的工作那么就添加什么样的 Handler 这里 SessionHandler 不是必须的但是默认是创建好的。 ServletHandler 主要负责处理 web 应用的 Servlet 、 Filter 等工作最后将请求直接交给 Servlet 、 Filter 都是在这里完成。 这里展示的 Handler 的启动过程其实是在准备 web 应用环境例如解析 web 应用的 web.xml 等等工作做好一切准备工作。 转载于:https://www.cnblogs.com/lovingprince/archive/2011/02/23/2166259.html