tomcat源码阅读-1
来源:互联网 发布:java对接微信公众平台 编辑:程序博客网 时间:2024/04/30 08:32
tomcat源码系列文章开始!!(不是为了说教,市面上讲tomcat的很多,我只是做笔记而已。。。)
虽然是tomcat源码系列的第一篇,但是其实是从第三章开始写的,原因嘛。。。因为我愿意这么写。。。
第三章源码分析:
主要类有以下几个:
1.启动类Bootstrap.class
2.连接器相关类HttpConnector.class和HttpProcessor.class
3.HTTP请求相关类HttpRequest.class,HttpResponse.class(以及两个facade类,主要是出于安全考虑,封装了组件内部的通信部分,只暴漏必要的部分)
4.请求处理类:静态资源处理类StaticResourceProcessor.class和动态资源处理类ServletProcessor.class
启动和处理请求流程如下:
1.首先Bootstrap启动类创建一个HttpConnector实例,该实例的类是一个实现了多线程接口的类,通过启动额外线程来监听相应地址和端口,并且阻塞等待请求到来:
while (!stopped) { // Accept the next incoming connection from the server socket Socket socket = null; try { socket = serverSocket.accept(); } catch (Exception e) { continue; } // Hand this socket off to an HttpProcessor HttpProcessor processor = new HttpProcessor(this); processor.process(socket); }
以上代码通过一个while循环来接受请求,这几乎是所有web服务器的实现方式(在一个循环中阻塞等待请求),每次接收到一个请求都会创建一个HttpProcessor实例来处理请求,该类的职责就是解析http请求并且创建和填充HttpRequest和HttpResponse对象,注意这个时候只是把http请求解析到了Httprequest中,具体请求参数等步骤并没有做,而是等到具体servlet实例调用getParamter()等方法的时候才会去解析,这样的好处就是不做不必要的解析,在需要的时候再解析,减少了CPU等开销。代码如下:
input = new SocketInputStream(socket.getInputStream(), 2048); output = socket.getOutputStream(); // create HttpRequest object and parse request = new HttpRequest(input); // create HttpResponse object response = new HttpResponse(output); response.setRequest(request); response.setHeader("Server", "Pyrmont Servlet Container"); parseRequest(input, output); parseHeaders(input);
接下来的一步就是根据请求的类型将请求传递给相应的动/静态处理器来处理:
//check if this is a request for a servlet or a static resource //a request for a servlet begins with "/servlet/" if (request.getRequestURI().startsWith("/servlet/")) { ServletProcessor processor = new ServletProcessor(); processor.process(request, response); } else { StaticResourceProcessor processor = new StaticResourceProcessor(); processor.process(request, response); }
静态处理器就不说了,这里再说一下动态(servlet)处理器部分的处理步骤:
1.首先通过解析url识别出请求的servlet名字
String uri = request.getRequestURI(); String servletName = uri.substring(uri.lastIndexOf("/") + 1);
2.然后创建一个类加载器,并且加载请求的servlet
URLClassLoader loader = null;try {// create a URLClassLoaderURL[] urls = new URL[1];URLStreamHandler streamHandler = null;File classPath = new File(Constants.WEB_ROOT);String repository = (new URL("file", null, classPath.getCanonicalPath() + File.separator)).toString() ;urls[0] = new URL(null, repository, streamHandler);loader = new URLClassLoader(urls);}catch (IOException e) {System.out.println(e.toString() );}Class myClass = null;try {myClass = loader.loadClass(servletName);}catch (ClassNotFoundException e) {System.out.println(e.toString());}
3.实例化servlet,调用service方法处理request(注意这里传入的是facade类)
servlet = (Servlet) myClass.newInstance(); HttpRequestFacade requestFacade = new HttpRequestFacade(request); HttpResponseFacade responseFacade = new HttpResponseFacade(response); servlet.service(requestFacade, responseFacade);
4.最后返回结果,结束请求
这里再次提一下,只有在加载的servlet方法中调用了request.getParameters()等方法,才会解析请求内容,并且只会解析一次。
解析步骤可以在HttpRequest类中找到,是调用了 parseParameters()方法
ok,基本上一个请求流程就是这样了,另外HttpRequest类中的很多方法值得细看,特别是一些同步的部分
0 0
- tomcat源码阅读-1
- Tomcat源码阅读1
- Tomcat源码阅读#1:classloader初始化
- tomcat源码阅读的趣事1
- tomcat源码阅读-2
- tomcat源码阅读-3.1
- Tomcat源码阅读计划
- Tomcat源码阅读
- Tomcat源码阅读系列
- Tomcat源码阅读二
- Tomcat源码阅读,标记下。
- Tomcat源码阅读,标记下
- tomcat 源码阅读步骤一
- tomcat源码阅读步骤二
- tomcat源码阅读步骤三
- tomcat源码阅读步骤四
- tomcat源码阅读步骤五
- tomcat源码阅读步骤六
- Axis1.4生成和调用Webservice
- Android适配器之CursorAdapter
- 我的栈
- 单片机其实很简单--前言
- HDU 1003 Max Sum
- tomcat源码阅读-1
- win7系统下安装matlab并正确配置
- ESC键坏了,VIM代替键
- Dynamic collapsible动态加载collapsible
- 结构型模7:代理模式(Proxy Pattern)
- 【索引】Counting:Examples
- LeetCode——Palindrome Partitioning II
- 层次遍历二叉树
- 【efm32】开发板 oled测试