- 浏览: 455847 次
- 性别:
- 来自: 大连
-
博客专栏
-
-
《Spring Secur...
浏览量:385794
文章分类
最新评论
-
蒙奇君杰:
必须感谢一番!!!愿开源的态度为更多的人所拥有,所 认同!
关于对《Spring Security3》一书的翻译说明 -
601235723:
bbjavaeye 写道你好,有个问题请教一下我配了<b ...
《Spring Security3》第四章第一部分翻译下(自定义的UserDetailsService) -
bay0902:
中国互联网的脊梁
Spring Security 3全文下载 -
hdcustc:
项目源码下载 微博网盘里的那个依赖文件损坏了啊 能否提供个可 ...
Spring Security 3全文下载 -
i641878506:
楼主辛苦, 可以提供原书的原项目文件的下载么
Spring Security 3全文下载
声明:源码版本为Tomcat 6.0.35
前面的文章中介绍了Tomcat的基本配置,每个配置项也基本上对应了Tomcat的组件结构,如果要用一张图来形象展现一下Tomcat组成的话,整个Tomcat的组成可以如下图所示:
Tomcat在接收到用户请求时,将会通过以上组件的协作来给最终用户产生响应。首先是最外层的Server和Service来提供整个运行环境的基础设施,而Connector通过指定的协议和接口来监听用户的请求,在对请求进行必要的处理和解析后将请求的内容传递给对应的容器,经过容器一层层的处理后,生成最终的响应信息,返回给客户端。
Tomcat的容器通过实现一系列的接口,来统一处理一些生命周期相关的操作,而Engine、Host、Context等容器通过实现Container接口来完成处理请求时统一的模式,具体表现为该类容器内部均有一个Pipeline结构,实际的业务处理都是通过在Pipeline上添加Valve来实现,这样就充分保证整个架构的高度可扩展性。Tomcat核心组件的类图如下图所示:
在介绍请求的处理过程时,将会详细介绍各个组件的作用和处理流程。本文将会主要分析Tomcat的启动流程,介绍涉及到什么组件以及初始化的过程,简单期间将会重点分析HTTP协议所对应Connector启动过程。
Tomcat在启动时的重点功能如下:
1、初始化类加载器:主要初始化CommonLoader、CatalinaLoader以及SharedLoader;
2、解析配置文件:使用Digester组件解析Tomcat的server.xml,初始化各个组件(包含各个web应用,解析对应的web.xml进行初始化);
3、初始化连接器:初始化声明的Connector,以指定的协议打开端口,等待请求。
不管是通过命令行启动还是通过Eclipse的WST server UI,Tomcat的启动流程是在org.apache.catalina.startup. Bootstrap类的main方法中开始的,在启动时,这个类的核心代码如下所示:
public static void main(String args[]) { if (daemon == null) { daemon = new Bootstrap();//实例化该类的一个实例 try { daemon.init();//进行初始化 } catch (Throwable t) { ……; } } try { ……//此处略去代码若干行 if (command.equals("start")) { daemon.setAwait(true); daemon.load(args);//执行load,生成组件实例并初始化 daemon.start();//启动各个组件 } ……//此处略去代码若干行 }
从以上的代码中,可以看到在Tomcat启动的时候,执行了三个关键方法即init、load、和start。后面的两个方法都是通过反射调用org.apache.catalina.startup.Catalina的同名方法完成的,所以后面在介绍时将会直接转到Catalina的同名方法。首先分析一下Bootstrap的init方法,在该方法中将会初始化一些全局的系统属性、初始化类加载器、通过反射得到Catalina实例,在这里我们重点看一下初始化类加载器的方法:
private void initClassLoaders() {
try { commonLoader = createClassLoader("common", null); if( commonLoader == null ) { // no config file, default to this loader - we might be in a 'single' env. commonLoader=this.getClass().getClassLoader(); } catalinaLoader = createClassLoader("server", commonLoader); sharedLoader = createClassLoader("shared", commonLoader); } catch (Throwable t) { log.error("Class loader creation threw exception", t); System.exit(1); } }
在以上的代码总,我们可以看到初始化了三个类加载器,这三个类加载器将会有篇博文进行简单的介绍。
然后我们进入Catalina的load方法:
public void load() { //…… //初始化Digester组件,定义了解析规则 Digester digester = createStartDigester(); //……中间略去代码若干,主要作用为将server.xml文件转换为输入流 try { inputSource.setByteStream(inputStream); digester.push(this); //通过Digester解析这个文件,在此过程中会初始化各个组件实例及其依赖关系 digester.parse(inputSource); inputStream.close(); } catch (Exception e) { } // 调用Server的initialize方法,初始化各个组件 if (getServer() instanceof Lifecycle) { try { getServer().initialize(); } catch (LifecycleException e) { if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE")) throw new java.lang.Error(e); else log.error("Catalina.start", e); } } }
在以上的代码中,关键的任务有两项即使用Digester组件按照给定的规则解析server.xml、调用Server的initialize方法。关于Digester组件的使用,后续会有一篇专门的博文进行讲解,而Server的initialize方法中,会发布事件并调用各个Service的initialize方法,从而级联完成各个组件的初始化。每个组件的初始化都是比较有意思的,但是我们限于篇幅先关注Connector的初始化,这可能是最值得关注的。
Connector的initialize方法,核心代码如下:
public void initialize() throws LifecycleException{ //该适配器会完成请求的真正处理 adapter = new CoyoteAdapter(this); //对于不同的实现,会有不同的ProtocolHandler实现类,我们来看 //Http11Protocol,它用来处理HTTP请求 protocolHandler.setAdapter(adapter); try { protocolHandler.init(); } catch (Exception e) { …… } }
在Http11Protocol的init方法中,核心代码如下:
public void init() throws Exception {
endpoint.setName(getName());//endpoint为JIoEndpoint的实现类 endpoint.setHandler(cHandler); try { endpoint.init();//核心代码就是调用 JIoEndpoint的初始化方法 } catch (Exception ex) { …… } }
我们看到最终的初始化方法最终都会调到JIoEndpoint的init方法,网络初始化和对请求的最初处理都是通过该类及其内部类完成的,所以后续的内容将会重点关注此类:
public void init() throws Exception { if (acceptorThreadCount == 0) {//接受请求的线程数 acceptorThreadCount = 1; } if (serverSocket == null) { try { if (address == null) { //基于特定端口创建一个ServerSocket对象,准备接受请求 serverSocket = serverSocketFactory.createSocket(port, backlog); } else { serverSocket = serverSocketFactory.createSocket(port, backlog, address); } } catch (BindException orig) { …… } } }
在上面的代码中,我们可以看到此时初始化了一个ServerSocket对象,用来准备接受请求。
如果将其比作赛跑,此时已经到了“各就各位”状态,就等最终的那声“发令枪”了,而Catalina的start方法就是“发令枪”啦:
public void start() { if (getServer() == null) { load(); } if (getServer() == null) { log.fatal("Cannot start server. Server instance is not configured."); return; } if (getServer() instanceof Lifecycle) { try { ((Lifecycle) getServer()).start(); } catch (LifecycleException e) { log.error("Catalina.start: ", e); } } //…… }
此时会调用Server的start方法,这里我们重点还是关注JIoEndpoint的start方法:
public void start() throws Exception { if (!initialized) { init(); } if (!running) { running = true; paused = false; if (executor == null) { //初始化处理连接的线程,maxThread的默认值为200,这也就是为什么 //说Tomcat只能同时处理200个请求的来历 workers = new WorkerStack(maxThreads); } for (int i = 0; i < acceptorThreadCount; i++) { //初始化接受请求的线程 Thread acceptorThread = new Thread(new Acceptor(), getName() + "-Acceptor-" + i); acceptorThread.setPriority(threadPriority); acceptorThread.setDaemon(daemon); acceptorThread.start(); } } }
从以上的代码,可以看到,如果没有在server.xml中声明Executor的话,将会使用内部的一个容量为200的线程池用来后续的请求处理。并且按照参数acceptorThreadCount的设置,初始化线程来接受请求。而Acceptor是真正的幕后英雄,接受请求并分派给处理过程:
protected class Acceptor implements Runnable { public void run() { while (running) { // 接受发送过来的请求 Socket socket = serverSocketFactory.acceptSocket(serverSocket); serverSocketFactory.initSocket(socket); //处理这个请求 if (!processSocket(socket)) { //关闭连接 try { socket.close(); } catch (IOException e) { // Ignore } } } } }
从这里我们可以看到,Acceptor接受Socket请求,并调用processSocket方法来进行请求的处理。至此,Tomcat的组件整装待命,等待请求的到来。关于请求的处理,会在下篇文章中介绍。
评论

public class ContactPerson {
private String personName;
private String mobileNumber;
private String email;
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
public String getMobileNumber() {
return mobileNumber;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
}
/*联系人*/
public class Recipient {
private List<ContactPerson> contactPersonList=new ArrayList();
public void addContactPerson(ContactPerson contactPerson){
this.contactPersonList.add(contactPerson);
}
public Iterator<ContactPerson> iterator(){
return contactPersonList.iterator();
}
}
/*邮件发送接口*/
public interface SMTransport {
public abstract void sendMessage(ShortMessage shortmessage);
}
/*使用手机短信的方式发送消息*/
public class CellPhoneTransport implements SMTransport {
public void sendMessage(ShortMessage shortmessage)
{
Recipient recipient = shortmessage.getRecipient();
Iterator it = recipient.iterator();
while(it.hasNext())
{
ContactPerson cp = it.next();
System.out.println("向手机号为"+cp.getMobileNumber()+"的联系人发送信息,内容:"+shortmessage.getContent());
}
}
}
/*使用邮件的方式发送消息*/
public class MailTransport implements SMTransport {
public void sendEmail(ShortMessage shortmessage)
{
Recipient recipient = shortmessage.getRecipient ();
Iterator it = recipient.iterator();
while(it.next())
{
ContactPerson cp = (ContactPerson)it.next();
System.out.println("向邮件地址为"+cp.getEmail()+"的联系人发送信息,内容:"+shortmessage.getContent());
}
}
}
/* 短消息核心类*/
public class ShortMessage {
private String content;
private Recipient recipient;
private SMTransport smTransport;
public void setRecipient(Recipient recipient){
this.recipient = recipient;
}
public Recipient getRecipient(){
return this.recipient;
}
public void setContent(String content){
this.content = content;
}
public String getContent(){
return this.content;
}
public void addTransport(SMTransport smTransport){
this.smTransport = smTransport;
}
public void send(){
smTransport.sendMessage(this);
}
}
发表评论
-
《Spring In Action》第三版译序
2013-07-12 12:19 3097《Spring In Action》第三 ... -
Tomcat源码解读系列(四)——Tomcat类加载机制概述
2012-09-23 22:23 10529声明:源码版本为Tomcat 6.0.35 ... -
Tomcat源码解读系列(三)——Tomcat对HTTP请求处理的整体流程
2012-09-09 22:34 6995声明:源码版本为Tomcat 6.0.35 前面的文章 ... -
Tomcat源码解读系列(一)——server.xml文件的配置
2012-08-25 07:31 6518Tomcat是JEE开发人员最常用到的开发工具,在Jav ... -
《Spring Security3》附录翻译(参考资料)
2012-02-13 22:58 6629附录:参考材料 在本附录中, ... -
《Spring Security3》第十三章翻译(迁移到Spring Security 3)
2012-02-13 22:50 5417第十三章 迁移到Spring Security 3 ... -
《Spring Security3》第十二章翻译(Spring Security扩展)
2012-02-13 22:38 8061第十二章 Spring Security扩展 ... -
《Spring Security3》第十一章(客户端证书认证)第二部分翻译
2012-02-13 22:23 5000在Spring Security中配置客户端证书认证 ... -
《Spring Security3》第十一章(客户端证书认证)第一部分翻译
2012-02-13 22:00 6242第十一章 客户端证书认证(Client Cert ... -
《Spring Security3》第十章(CAS)第二部分翻译(CAS高级配置)
2012-01-19 13:07 8659高级CAS配置 ... -
《Spring Security3》第十章(CAS)第一部分翻译(CAS基本配置)
2012-01-19 12:54 12382第十章 使用中心认证服务(CAS)进行单点登录 ... -
《Spring Security3》第九章(LDAP)第三部分翻译(LDAP明确配置)
2012-01-19 12:44 6472明确的LDAP bean配置 ... -
《Spring Security3》第九章(LDAP)第二部分翻译(LDAP高级配置)
2012-01-19 12:36 7249LDAP的高级配置 一旦我们 ... -
《Spring Security3》第九章(LDAP)第一部分翻译(LDAP基本配置)
2012-01-19 12:22 6223第九章 LDAP目录服务 在本章中,我们 ... -
《Spring Security3》第八章第三部分翻译(属性交换)
2012-01-18 15:46 2974属性交换(Attribute Exchange) ... -
《Spring Security3》第八章第二部分翻译(OpenID用户的注册)
2012-01-18 13:39 5441OpenID用户的注册问 ... -
《Spring Security3》第八章第一部分翻译(OpenID与Spring Security)
2012-01-17 22:38 7578第八章 对OpenID开放 OpenID是 ... -
《Spring Security3》第七章第三部分翻译(ACL的注意事项)
2012-01-17 22:25 2724典型ACL部署所要考虑的事情 ... -
《Spring Security3》第七章第二部分翻译(高级ACL)(下)
2012-01-17 22:17 4225支持ACL的Spring表达式语言 SpEL对A ... -
《Spring Security3》第七章第二部分翻译(高级ACL)(上)
2012-01-10 22:59 4713高级ACL话题 一些高级的话 ...
相关推荐
### tomcat源码解析 #### 简介与概览 Tomcat作为一款开源的Servlet容器,被广泛应用于Java Web应用的开发与部署环境中。它不仅支持Servlet API,还支持JSP规范,使得开发者能够轻松地构建动态网页。本文旨在深入...
"JSP源码——图片浏览小程序(java+applet).zip" 这个标题揭示了我们要讨论的是一个基于Java Server Pages (JSP) 技术的源代码项目,其主要功能是一个用于浏览图片的小应用程序。这里的关键词“java+applet”暗示这个...
《Java毕业设计——学校管理系统设计与实现》是一...以上内容仅是对该毕业设计项目的一般性解读,具体实现细节还需参考源码和数据库设计。通过这个项目,学生可以深入理解Java Web开发的全流程,提升实际问题解决能力。
"精选_基于SSM实现旅游网站项目_源码打包" 这个标题揭示了我们讨论的核心——一个精选的旅游网站项目,它采用的是SSM框架进行开发,并且提供了完整的源码供学习和参考。SSM是Spring、Spring MVC和MyBatis的缩写,这...
通过查看和分析源码,开发者不仅可以学习到JSP和Servlet的相关知识,还可以了解数据库交互、用户认证、权限管理等Web开发中的核心概念。这对于提升个人技能和理解Web应用程序的构建至关重要。 在部署JEEBBS 1.0 ...
源代码分析对于深入理解框架的工作原理至关重要,通过阅读和研究源码,我们可以了解到Spring如何处理依赖注入、事务管理、AOP(面向切面编程)以及数据访问等核心功能。 另一个标签 "工具" 可能指的是开发过程中...
《Java商城源码解析——以jshopv2releasesource为例》 在电子商务领域,Java作为后端开发的主流语言,被广泛应用于构建各种类型的网上商城系统。"jshopv2releasesource"是一个基于Java的开源商城项目,它为我们提供...
根据给定文件的信息,本文将围绕“木版年画技艺传承资源管理系统”的设计与实现进行深入探讨,重点分析用户功能及管理员功能,并结合具体的研究内容和技术背景,为读者提供一个全面的技术解读。 ### 一、研究背景与...