Jetty源码分析之AbstractHandler

来源:互联网 发布:textmessage java 编辑:程序博客网 时间:2024/05/19 20:42

jetty可以说是一个基于Handler设计的Web服务器,其通过组合各种Handler实现对请求的处理。所以源码阅读部分先从Handler部分开始,而AbstractHandler是大部分Handler都继承了的父类,因此先了解它的源码。下面先来看下AbstractHandler的类图,了解下它的继承关系。
这里写图片描述

从类图上就可以看到AbstractHandler实现了LifeCycle和Handler两个接口,所以同时具备这两个类的特性。
对于Handler接口,其实里面主要定义了一个处理请求的handle()方法。

public interface Handler extends LifeCycle, Destroyable{   //target 请求的目标,一般是个url   //baseRequest 还未包装过的请求   //request 包装之后得到的HttpServletRequest   //response 保证之后得到的HttpServletResponse   //Handler负责对请求进行处理,对外提供的处理请求的就是handle()方法.    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)        throws IOException, ServletException;    public void setServer(Server server);    public Server getServer();    public void destroy();}

对于LifeCycle接口这里继承的是其一个子类AggregateLifeCycle,这个类是定义用来管理集合类的生命周期的,它里面持有一个List<Bean> _beans,可以将一些组件加入到这个list中,如果这些组件实现了LifeCycle接口,则AggregateLifeCycle统一负责管理它们的生命周期—在AggregateLifeCycle启动的时候启动这些组件,在AggregateLifeCycle停止的时候停止这些组件。下面是其部分源码:

 private final List<Bean> _beans=new CopyOnWriteArrayList<Bean>();    private boolean _started=false;   //定义的一个内部类    private class Bean    {        Bean(Object b)        {            _bean=b;        }        final Object _bean;        volatile boolean _managed=true;        public String toString()        {            return "{"+_bean+","+_managed+"}";        }    }   //会依次启动管理的所有未启动的LifeCycle组件    @Override    protected void doStart() throws Exception    {        for (Bean b:_beans)        {            if (b._managed && b._bean instanceof LifeCycle)            {                LifeCycle l=(LifeCycle)b._bean;                if (!l.isRunning())                    l.start();            }        }        // indicate that we are started, so that addBean will start other beans added.        _started=true;        super.doStart();    }    //添加一个组件,并且指定是否被管理,如果不指定为被管理组件,    //则AggregateLifeCycle不复杂管理它们的生命周期    public boolean addBean(Object o, boolean managed)    {        if (contains(o))            return false;        Bean b = new Bean(o);        b._managed=managed;        _beans.add(b);        if (o instanceof LifeCycle)        {            LifeCycle l=(LifeCycle)o;            // Start the bean if we are started            if (managed && _started)            {                try                {                    l.start();                }                catch(Exception e)                {                    throw new RuntimeException (e);                }            }        }        return true;    }

其实分析了上面两个继承的父类之后, AbstractHandler中基本就分析完了,因为AbstractHandler本身没有对父类的关键方法,比如doStart()和doStop()进行重写,也没有实现handle()方法(留给具体的子类去实现了),唯一重写的一个方法就是setServer()方法。AbstractHandler的全部源码如下:

public abstract class AbstractHandler extends AggregateLifeCycle implements Handler{    private static final Logger LOG = Log.getLogger(AbstractHandler.class);    private Server _server;    public AbstractHandler()    {    }    //仅仅是简单的调用父类的doStart(),没有加任何新逻辑    @Override    protected void doStart() throws Exception    {        LOG.debug("starting {}",this);        super.doStart();    }    @Override    protected void doStop() throws Exception    {        LOG.debug("stopping {}",this);        super.doStop();    }   //重写了Handler接口中的setServer()方法    public void setServer(Server server)    {        Server old_server=_server;        //server中持有其管理的所有组件的引用,所以下面会有remove和add操作        if (old_server!=null && old_server!=server)            old_server.getContainer().removeBean(this);        _server=server;        if (_server!=null && _server!=old_server)            _server.getContainer().addBean(this);    }    public Server getServer()    {        return _server;    }    public void destroy()    {        if (!isStopped())            throw new IllegalStateException("!STOPPED");        super.destroy();        if (_server!=null)            _server.getContainer().removeBean(this);    }    public void dumpThis(Appendable out) throws IOException    {        out.append(toString()).append(" - ").append(getState()).append('\n');    }}