深入Jetty源码之Servlet框架及实现(Servlet、Filter、Registration)

概述


Servlet是Server
Applet的缩写,即在服务器端运行的小程序,而Servlet框架则是对HTTP服务器(Servlet
Container)和用户小程序中间层的标准化和抽象。这一层抽象隔离了HTTP服务器的实现细节,而Servlet规范定义了各个类的行为,从而保证了这些“服务器端运行的小程序”对服务器实现的无关性(即提升了其可移植性)。
在Servlet规范有以下几个核心类(接口):
ServletContext:定义了一些可以和Servlet
Container交互的方法。
Registration:实现Filter和Servlet的动态注册。
ServletRequest(HttpServletRequest):对HTTP请求消息的封装。
ServletResponse(HttpServletResponse):对HTTP响应消息的封装。
RequestDispatcher:将当前请求分发给另一个URL,甚至ServletContext以实现进一步的处理。
Servlet(HttpServlet):所有“服务器小程序”要实现了接口,这些“服务器小程序”重写doGet、doPost、doPut、doHead、doDelete、doOption、doTrace等方法(HttpServlet)以实现响应请求的相关逻辑。
Filter(FilterChain):在进入Servlet前以及出Servlet以后添加一些用户自定义的逻辑,以实现一些横切面相关的功能,如用户验证、日志打印等功能。
AsyncContext:实现异步请求处理。

Jetty中的Holder

在Jetty中,每个Servlet和其相关信息都由ServletHolder封装,并且将Servlet相关操作代理给ServletHolder;同理,对Filter也有FilterHolder与其相对应;另外ServletHolder和FilterHolder都继承自Holder实例。在Servlet
3.0中引入动态向ServletContext注册Servlet和Filter,并返回相应的Registration实例,用于进一步配置与其关联的Servlet和Filter,因而Registration也是和ServletHolde和FilterHolder相关联的接口。在Jetty中,他们的类关系图如下:

Servlet

Servlet和Filter是Servlet规范中用于定义用户逻辑实现的接口,Servlet是最初的版本,所有的“服务器端小程序”都要实现该接口,并交由Servlet
Container管理其实例,负责其生命周期,以及当相应请求到来时调用相应方法。Servlet接口非常简单:

public interface Servlet {
    // Servlet
Container在创建一个Servlet后调用该方法,并传入ServletConfig实例,从而用户可以在这个方法中做一些自定义的初始化工作,如初始化数据库连接等。
 
  // 并且Servlet
Container可以保证一个Servlet实例init方法之后被调用一次,但是对一个Servlet类init方法可能会被多次调用,因而有些Servlet
Container可能会在某些情况下将某些
    // Servlet移出Servlet
Container,而后又重新加载这些Servlet,如为了在处理Servlet
Container资源压力比较大的情况下。
    public void init(ServletConfig config) throws ServletException;

    //
返回在init方法中传入的ServletConfig实例。ServletConfig包含了在web.xml配置文件中配置当前Servlet的初始化参数,并且可以使用该ServletConfig实例获取当前ServletContext实例。
    public ServletConfig getServletConfig();
    
    // 当该Servlet对应的请求到来时,Servlet
Container会调用这个Servlet的service方法,用于处理请求,并将相应写入ServletResponse参数中,该方法只能在init方法完成后被调用。
 
  //
在service方法中,可以选择使用ServletResponse定义的方法返回响应给客户端,或只是向ServletResponse中写入响应,最终由Servlet
Container根据ServletResponse的信息将响应返回给客户端。
    // 很多情况下,Servlet
Container都不会使用多线程来处理客户请求,应该该方法会在多线程环境下被使用,Servlet实现者可以实现SingleThreadMode接口以强制该方法只在单线程的环境下被使用。
 
  // 但是SingleThreadMode接口已经在Servlet
2.3中被废弃,实现该接口也会影响Servlet的执行性能,而且有些Servlet
Container会选择实例或多个Servlet实例,以保证对请求的响应性能,因而此时依然不能保证该方法的单线程特性,因而不建议使用这个SingleThreadMode接口。
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
    
    //
返回当前Servlet的描述信息,如作者、版本号、版权等。在GenericServlet默认实现中,返回空字符串。
    public String getServletInfo();

    // 当Servlet
Container销毁当前Servlet时会调用该方法,从而给Servlet提供拥有清理当前Servlet占用的资源的地方,如关闭和数据库的连接等。
 
  // Servlet Container会保证该方法在所有执行service方法的线程完成或超时后被调用。Servlet
Container一般会在三种情况下会调用该方法:
    // 1. Servlet
Container当前资源比较紧张,需要将一些不再用或不常用的Servlet移出;2. 实现某些Servlet的热部署;3. 当前Web
Application被停止。
    public void destroy();
}

对每个Servlet都有一个ServletConfig实例和其对应,ServletConfig中包含了在web.xml文件中定义的Servlet的init-param参数,并且可以使用ServletConfig实例获取ServletContext实例:

public interface ServletConfig {
    //
返回该ServletConfig对应的Servlet的名称,在web.xml文件中定义的Servlet名称或对于没有注册的Servlet为其类名。
    public String getServletName();

    //
返回和其关联的ServletContext。
    public ServletContext getServletContext();
    
    //
返回在web.xml配置文件中定义或者使用ServletRegistration动态定义添加的init-param参数。
    public String getInitParameter(String name);
    public Enumeration<String> getInitParameterNames();
}

在Jetty中,不管是在web.xml中配置的Servlet还是使用ServletContext动态注册并使用ServletRegistration.Dynamic动态配置的Servlet,在ServletHandler内部都使用ServletHolder来表示一个Servlet,并且由ServletHolder来处理所有和Servlet相关的逻辑。ServletHolder的实现逻辑在之后给出。
Servlet框架中默认实现了两个Servlet:GenericServlet和HttpServlet,GenericServlet只是对Servlet的简单实现,而HttpServlet会根据请求中的方法将请求分发给相应的:doGet/doPost/doPut/doHead/doOptions/doTrace等方法,它还提供了getLastModified()方法,重写该方法用于实现条件GET。以上这些方法(除doOptions和doTrace已经有具体的逻辑实现)默认实现直接方法405
Method Not Allowed响应(Http/1.1)或404 Bad
Request响应(HTTP/1.0)。重写相应的方法以实现各个Method对应的逻辑。

Filter

在Servlet
2.3开始引入了Filter机制,以在Servlet的service方法的执行前后添加一些公共的Filter逻辑,为面向切面的编程提供了很大的便利,这些公共的逻辑如纪录一个Request从进入Servlet
Container到出所花费的总时间、为每个Request添加一些额外的信息以帮助之后处理、对所有或特定Request添加用户验证功能等。Filter可以在web.xml文件中定义,由Servlet
Container负责其实例化、初始化以及doFilter方法的调用。在Servlet
3.0以后,还支持动态的给ServletContext注册Filter,并由返回的FilterRegistration.Dynamic实例做进一步的配置。Filter的接口定义也是比较简单:

public interface Filter {
    //
由ServletContainer在初始化一个Filter时调用,Filter的实现者可以在该方法中添加一些用户自定义的初始化逻辑,同时可以保存FilterConfig实例,它可以获取定义的init-param初始化参数以及获取ServletContext实例。其他情况和Servlet类似,不赘述。
    public void init(FilterConfig filterConfig) throws ServletException;
    
    //
每一次请求到来都会穿越配置的FilterChain,执行配置的Servlet,然后从这个FilterChain中返回。在doFilter方法的实现中,要调用下一个Filter,使用FilterChain的doFilter方法。
 
  //
在调用FilterChain的doFilter之前为执行请求之前的处理,而之后为请求已经执行完成,在响应返回的路上的逻辑处理。也可以步调用FilterChain的doFilter方法,以阻止请求的进一步处理。
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException;

    // 在Filter被移出Servlet
Container时调用,它和Servlet类似,不赘述。**
    public void destroy();
}

Filter接口中包含对FilterConfig以及FilterChain的使用,FilterConfig和ServletConfig定义、实现以及逻辑都类似:

public interface FilterConfig {
    public String getFilterName();
    public ServletContext getServletContext();
    public String getInitParameter(String name);
    public Enumeration<String> getInitParameterNames();
}

FilterChain是Servlet中将Filter链以Channel的方式连接在一起的类,它实现了可以向执行Servlet前和后都添加一些切面逻辑,甚至阻止Servlet的执行,Filter的实现者使用FilterChain的doFilter方法调用在这个链中的下一个Filter的doFilter方法,如果当前Filter是链中最后一个Filter,则调用响应的Servlet。其接口定义如下:

public interface FilterChain {
    //
调用该方法会调用Filter链中的下一个Filter的doFilter方法,如果当前Filter是这条链中的最后一个Filter,则该方法会调用响应的Servlet的service方法。
    public void doFilter (ServletRequest request, ServletResponse response) throws IOException, ServletException;
}

在Jetty中,ServletHandler的内部类Chain实现了FilterChain接口,在构造Chain实例时,首先根据Request的URL以及对应Servlet
Name查找所有相关的Filter列表,然后使用这个Filter列表、Request实例、当前请求对应的ServletHolder创建这个链,在其doFilter方法实现中,它会存储一个_filter索引,它指向下一个Filter实例,当每个Filter调用doFilter方法时,Chain会根据这个索引获取下一个Filter实例,并将该索引向后移动,从而调用下一个Filter的doFilter方法,如果这个索引值到达最后一个Filter链中的Filter,且有ServletHolder实例存在,则调用该ServletHolder的handle方法,否则调用notFound方法,即向客户端发送404
NOT
FOUND响应。如果Filter不支持ASYNC模式,则在调用其doFilter之前,需要将Request的ASYNC支持设置为false。
在ServletHandler中还有CachedChain实现了FilterChain接口,它以链表的形式纪录找到的Filter列表,并将这个列表缓存在ServletHandler中,不同的dispatch类型有一个列表,并且可以根据请求的URL或请求的Servlet名来查找是否已经有缓存的Filter链表。
在ServletHandler中,可以使用setFilterChainsCached方法来配置是否使用CachedChain还是直接使用Chain,默认使用CachedChain。

Registration

Registration是Servlet
3.0规范中引入的接口,用于表示向ServletContext中动态注册的Servlet、Filter的实例,从而实现对这些动态注册的Servlet、Filter实例进行进一步的配置。
对于Servlet和Filter的配置,他们的共同点是他们有响应的Name、ClassName、Init
Parameters以及asyncSupported属性,而这些方法正是Registration接口的定义。Registration接口将setAsyncSupport方法定义在其内部的Dynamic接口中,Dynamic用于表示这是用于动态的配置这个Servlet或Filter的含义,但是为什么要将这个方法放在Dynamic接口中呢?如何决定不同的方法应该是在Registration本身的接口中,而那些应该放到Dynamic接口中呢?

public interface Registration {
    //
返回这个Registration实例关联的Servlet或Filter的Name,这个Name在向ServletContext注册Servlet或Filter时给定。
    public String getName();

    //
返回这个Registration实例关联的Servlet或Filter的类名。
    public String getClassName();

    //
和这个Registration实例关联的初始化参数的操作。
    public boolean setInitParameter(String name, String value);
    public String getInitParameter(String name);
 
  public Set<String> setInitParameters(Map<String, String> initParameters);
    public Map<String, String> getInitParameters();

    interface Dynamic extends Registration {
        //
配置Registration关联的Servlet或Filter是否支持异步操作。
        public void setAsyncSupported(boolean isAsyncSupported);
    }
}

Registration有两个子接口:ServletRegistration和FilterRegistration,分别用于表示Servlet相关的配置和Filter相关的配置。
对ServletRegistration,它可以设置Servlet的URL
Mapping、RunAsRole属性、LoadOnStartup属性等:

public interface ServletRegistration extends Registration {
    // 添加URL
patterns到这个ServletRegistration关联的Servlet的映射。如果有任意的URL
patterns已经映射到其他的Servlet中,则该方法不会执行任何行为。
    public Set<String> addMapping(String... urlPatterns);

    // 获取所有到当前ServletRegistration对应的Servlet的URL
patterns。
    public Collection<String> getMappings();

    //
获取当前ServletRegistration对应的Servlet的RunAsRole。
    public String getRunAsRole();

    interface Dynamic extends ServletRegistration, Registration.Dynamic {
        //
设置当前ServletRegistration对应的Servlet的loadOnStartup等级。如果loadOnStartup大于或等于0,表示Servlet
Container要优先初始化该Servlet,
        // 此时Servlet
Container要在Container初始化时实例化并初始化该Servlet,即在所有注册的ContextListener的contextInitialized方法调用完成后。
 
      //
如果loadOnStartup小于0,则表示这个Servlet可以在用到的时候实例化并初始化。默认值为-1。
        public void setLoadOnStartup(int loadOnStartup);

        //
设置ServletRegistration相关的ServletSecurityElement属性。
        public Set<String> setServletSecurity(ServletSecurityElement constraint);

        //
设置ServletRegistration对应的Servlet的MultipartConfigElement属性。
        public void setMultipartConfig(MultipartConfigElement multipartConfig);

        //
设置ServletRegistration对应的Servlet的RunAsRole属性。
        public void setRunAsRole(String roleName);
    }
}

对FilterRegistration,它可以配置Filter的URL
Mapping和Servlet Mapping等:

public interface FilterRegistration extends Registration {
    //
添加FilterRegistration关联的Filter到Servlet的映射,使用Servlet
Name、DispatcherType作为映射。isMatchAfter表示新添加的Mapping是在已有的Mapping之前还是之后。
 
  public void addMappingForServletNames(EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter, String... servletNames);

    // 获取当前FilterRegistration关联的Filter已存在的到Servlet
Name的映射。
    public Collection<String> getServletNameMappings();

 
  //
添加FilterRegistration关联的Filter到Servlet的映射,使用URL
patterns、DispatcherType作为映射。isMatchAfter表示新添加的Mapping是在已有的Mapping之前还是之后。
    public void addMappingForUrlPatterns(EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter, String... urlPatterns);

 
  //
获取当前FilterRegistration关联的Filter已存在的到URL
patterns的映射。
    public Collection<String> getUrlPatternMappings();

    interface Dynamic extends FilterRegistration, Registration.Dynamic {
    }
}

在Jetty中对Registration的实现在Holder中定义,而相应的ServletRegistration和FilterRegistration实现作为ServletHolder和FilterHolder中的内部类实现,具体参考这两个类的实现。

Holder实现

在之前有提到,在Jetty中Servlet和Filter由相应的ServletHolder和FilterHolder封装,以将Servlet/Filter相关的信息和配置放在一起,并处理各自相关的逻辑,即面向对象设计中的将数据靠近操作。由于Servlet和Filter有一些相同的配置和逻辑,因而在ServletHolder和FilterHolder中提取出了Holder父类。在Holder的实现中,它主要定义了一些Servlet和Filter都要使用的字段,比高实现了所有和InitParameter相关的操作:

public enum Source { EMBEDDED, JAVAX_API, DESCRIPTOR, ANNOTATION };
    final private Source _source;
    protected transient Class<? extends T> _class;
    protected final Map<String,String> _initParams=new HashMap<String,String>(3);
    protected String _className;
    protected String _displayName;
    protected boolean _extInstance;
    protected boolean _asyncSupported=true;
    protected String _name;
    protected ServletHandler _servletHandler;

Holder继承自AbstractLifeCycle,它在start时,如果_class字段没有被设置,则会使用ClassLoader加载_className中指定的类实例并赋值给_class字段;Source只是目前只是一种元数据的形式存在,用于表示Servlet或Filter的来源;而extInstance用于表示Servlet和Filter实例是直接通过ServletContext注册而来,而不是在当前Holder内部创建。
在Holder类中还定了两个内部类:HolderConfig和HolderRegistration,其中HoldConfig实现了ServletConfig/FilterConfig相关的所有InitParameter相关的操作(代理给Holder);HolderRegistration实现了Registration.Dynamic接口,其实现也都代理给Holder类中的方法。

FilterHolder实现

FilterHolder实现比较简单,它直接继承自Holder类,它额外的包含了一下几个字段:

private transient Filter _filter;
    private transient Config _config;
    private transient FilterRegistration.Dynamic _registration;

其中_filter字段在start时如果没有初始化,则使用ServletContext创建该Filter实例,而_config字段则在启动时直接创建Config实例(Config是FilterHolder的内部类,且它继承自HolderConfig,并实现了FilterConfig接口),最后调用_filter.init()方法并传入_config实例。在stop时,调用_filter.destroy()方法从而该Filter有机会做一些清理工作,并且调用ServletHandler中的destroyFilter()方法,以通知ContextHandler中定义的Decorators。在注册外部实例化的Filter时,设置_extInstance为true,同时更新_class字段,以及_name字段(如果_name字段未被设置的话)。
最后,FilterHolder中还定义了Registration内部类,它继承自HolderRegistration,并实现了FilterRegistration.Dynamic接口。该Registration内部类实现了Mapping相关方法,Jetty中使用FilterMapping来表达一个Filter的映射关系。在FilterMapping中定义了一下映射关系:

private int _dispatches=DEFAULT;
    private String _filterName;
    private transient FilterHolder _holder;
    private String[] _pathSpecs;
    private String[] _servletNames;

它包含了两个appliesTo()方法,这两个方法在Chain用于根据dispatcherType或dispatcherType以及path计算当前FilterMapping是否匹配给定的dispatcherType或dispatcherType和path。在对dispatcherType做匹配计算时,使用FilterMapping实例的没有设置dispatcherType集合,它依然匹配REQUEST或ASYNC(如果Filter支持ASYNC模式的话)。

boolean appliesTo(int type) {
        if (_dispatches==0)
            return type==REQUEST || type==ASYNC && _holder.isAsyncSupported();
        return (_dispatches&type)!=0;
    }

ServletHolder实现

ServletHolder实现相对复杂,它继承自Holder类,并实现了UserIdentity.Scope接口以及Comparable接口,其中Comparable接口用于当ServletHandler在start时,对注册的所有ServletHolder的数组排序以决定他们的start顺序。它包含了一下额外的字段:

private int _initOrder;
    private boolean _initOnStartup=false;
    private Map<String, String> _roleMap;
    private String _forcedPath;
    private String _runAsRole;
    private RunAsToken _runAsToken;
    private IdentityService _identityService;
    private ServletRegistration.Dynamic _registration;
    private transient Servlet _servlet;
    private transient Config _config;
    private transient long _unavailable;
    private transient UnavailableException _unavailableEx;
 
  public static final Map<String,String> NO_MAPPED_ROLES = Collections.emptyMap();

其中_initOrder为ServletRegistration.Dynamic接口的实现,它定义ServletHolder在ServletHandler中的start顺序,即compareTo()方法的实现的主要参考信息。在Jetty中,只要设置了loadOnStart字段,则它就会在start时被初始化(即使设置的值为负数)。在设置外部Servlet实例直接到ServletHolder中时,_extInstance字段为被设置为true。如果在web.xml中的Servlet定义中有jsp-file定义,则设置该ServletHolder的forcePath值为该jsp-file中定义的值,而其className的值为servlet-class的定义,此时在ServletHolder的handle方法中会将forcePath的值设置到Request的org.apache.catalina.jsp_file属性中(这个设置用来干嘛呢?还不了解。。。);在ServletHolder启动时,如果Servlet实例实现了SingleThreadModel接口,则Servlet实例使用SingleThreadedWrapper类来表示(它包含一个Servlet栈
,对每次请求,它会复用以前已经创建的Servlet实例或者创建一个新的实例以处理当前的请求,即该Servlet会有多个实例),如果_extInstance为true或者配置了loadOnStart属性,则在ServletHolder启动是就会初始化这个Servlet(实例化Servlet,并调用Servlet的init方法)。当一个请求到来时,ServletHolder调用其handle方法以处理该请求,在该方法中调用Servlet的service方法,如果在处理过程中出错了,则在Request中设置javax.servlet.error.servlet_name属性为ServletHolder的Name属性。

类似FilterMapping,Jetty也使用ServletMapping表达Servlet和URL
pattern的映射关系:

private String[] _pathSpecs;
    private String _servletName;

其他Security相关的字段和逻辑暂不做介绍。。。。。

深入Jetty源码之Servlet框架及实现(Servlet、Filter、Registration),布布扣,bubuko.com

时间: 2024-10-12 18:51:28

深入Jetty源码之Servlet框架及实现(Servlet、Filter、Registration)的相关文章

TOMCAT源码分析(启动框架)

建议: 毕竟TOMCAT的框架还是比较复杂的, 单是从文字上理解, 是不那么容易掌握TOMCAT的框架的. 所以得实践.实践.再实践. 建议下载一份TOMCAT的源码, 调试通过, 然后单步跟踪其启动过程. 如果有不明白的地方, 再来查阅本文, 看是否能得到帮助. 我相信这样效果以及学习速度都会好很多! 1. Tomcat的整体框架结构 Tomcat的基本框架, 分为4个层次. Top Level Elements: Server Service Connector HTTP AJP Conta

Jetty源码学习-编译Jetty源码二三事

工作小几个月了,JDK基础和web应用框架学的的差不多了,开始学习Jetty源码,费了小半天才编译成功,把自己拆过的坑记录下来. 编译前的环境: MAVEN 3.3.Eclips eLuna Service Release 1 (4.4.1) 下载好MAVEN后,得把Eclipse中的maven配置为下载的MAVEN具体请搜索其他博文参考! 下载源码 导入eclipse 编译源码 1.下载源码 1.1 Jetty源码可以方便的在Github的Jetty工程主页上下载,链接. 1.2 进入主页后,

Solr4.9.0源码分析(1)之Solr的Servlet

Solr是作为一个Servlet运行在Tomcat里面的,可以查看Solr的web.xml. 1.web.xml配置 由web.xml可以看出,基本上所有Solr的操作都是在SolrDispatchFilter中实现的.当输入http://localhost:8080/solr/前缀的URL就会触发SolrDispatchFilter. 1 <filter> 2 <filter-name>SolrRequestFilter</filter-name> 3 <fil

jetty源码剖析

最近使用jetty自己写了一个web server,现在闲了花了一天的时间看了一jetty的源代码,主要以server的启动为主线,进行了剖析,经过阅读对jetty的源码大赞,写的简洁.清晰,架构也不复杂,好多东西值得借鉴.具体代码级别的剖析也不便在这贴了,提供一篇在阅读源码时的预备文章,见下面网址. jetty的工作原理以及与tomcat的比较:http://www.ibm.com/developerworks/cn/java/j-lo-jetty/ jetty源码剖析,布布扣,bubuko.

nginx源码分析--从源码看nginx框架总结

nginx源码总结: 1)代码中没有特别绕特别别扭的编码实现,从变量的定义调用函数的实现封装,都非常恰当,比如从函数命名或者变量命名就可以看出来定义的大体意义,函数的基本功能,再好的架构实现在编码习惯差的人实现也会黯然失色,如果透彻理解代码的实现,领悟架构的设计初衷,觉得每块代码就想经过耐心雕琢一样,不仅仅实现了基本的功能给你,为其他人阅读也会提供很好的支持.细致恰当的命名规则就可以看出作者的功力. 2)更好更高的软件性能体现在架构设计上,好的架构会让软件更加稳定.容易维护.便于扩展.从核心模块

HsqlDB源码学习——基本框架概览

Database: Database is the root class for HSQL Database Engine database.It holds the data structures that form an HSQLDB database instance. 整个体系结构大致如上图!接下来便一个一个学习,多么蛋疼的过程! HsqlDB源码学习--基本框架概览

Jetty 源码分析

一. 总括 你了解Jetty 吗,就像我们所熟知的Tomcat一样, Jetty是一个免费的开放源码的100%纯Java的Http服务器和Servlet容器. Jetty具备以下特点: 快速高效 .Jetty是最快的Servlet服务器之一      .Jetty可以处理上千个并发连接      小巧嵌入      .Jetty的jar只有600多K      .可动态嵌入到应用程序,适合开发web2.0等应用 应用广泛 .开源项目有Geronimo, JBoss, JOnAS等 .商业项目有I

Spring5源码解析-Spring框架中的事件和监听器

事件和平时所用的回调思想在与GUI(JavaScript,Swing)相关的技术中非常流行.而在Web应用程序的服务器端,我们很少去直接使用.但这并不意味着我们无法在服务端去实现一个面向事件的体系结构. 在本文中,我们将重点介绍Spring框架中的事件处理.首先,会先介绍下事件驱动编程这个概念.接着,我们会将精力放在专门用于Spring框架中的事件处理之上.然后我们会看到实现事件调度和监听的主要方法.最后,我们将在Spring应用程序中展示如何使用基本的监听器. 事件驱动编程 在开始讨论事件驱动

libevent高性能网络库源码分析——事件处理框架(四)

event_base结构 event_base的初始化 接口函数 libevent中基于Reactor模式的事件处理框架对应event_base,在event在完成创建后,需要向event_base注册事件,监控事件的当前状态,当事件状态为激活状(EV_ACTIVE)时,调用回调函数执行.本文主要从以下几方面进行分析:event_base的结构,event_base的创建,事件的注册.事件分发.事件注销 event_base结构 struct event_base { //指定某个eventop