ScopedHandler在Jetty的Handler体系中属于比较重要的一个成员,像ContextHandler、SessionHandler、ServletHandler、WebappContext等重要组件都直接或间接的继承了ScopedHandler,所以在学习其它更具体handler之前,先来分析下它的源码。先来看下ScopedHandler的类图:
从类图中可以看到继承的层次比较深,所以还是从父类开始分析,LifeCycle接口和AbstractHandler前面已经分析过,就不再次分析了。
1.HandlerContainer和AbstractHandlerContainer
HandlerContainer是一个接口,它的定义是一个包含其它Handlers的Handler。也就是本身是一个handler但又可以看成是可以持有其它handler的Handler容器,接口的源码比较简单,四个方法的含义都比较容易理解:
/**
* A Handler that contains other Handlers.
* <p>
* The contained handlers may be one (see @{link {@link org.eclipse.jetty.server.handler.HandlerWrapper})
* or many (see {@link org.eclipse.jetty.server.handler.HandlerList} or {@link org.eclipse.jetty.server.handler.HandlerCollection}.
*
*/
public interface HandlerContainer extends LifeCycle
{
//以数组形式返回含有的handlers
public Handler[] getHandlers();
//以数组形式返回含有的handler以及这些handler的子Handler
public Handler[] getChildHandlers();
//以数组形式返回ChildHandlers中类型为byclass类型的Handler
public Handler[] getChildHandlersByClass(Class<?> byclass);
//返回ChildHandlers中第一个类型为byclass的Handler
public <T extends Handler> T getChildHandlerByClass(Class<T> byclass);
}
从类图上就可以看到AbstractHandlerContainer实现了HandleContainer并且继承了AbstractHandler,上面说到HandlerContainer的定义是既是一个Handler又是Handler容器,但因为它没有实现Handler接口所以并不能算是一个Handler,所以只有AbstractHandlerContainer才完全符合上面的定义,它事实上也是所有HandlerContainer子类的父类。
AbstractHandlerContainer实现了HandlerContainer接口中的后三个方法,getHandlers()方法留给了子类去实现。源码如下:
public Handler[] getChildHandlers()
{
Object list = expandChildren(null,null);
return (Handler[])LazyList.toArray(list, Handler.class);
}
/* ------------------------------------------------------------ */
public Handler[] getChildHandlersByClass(Class<?> byclass)
{
Object list = expandChildren(null,byclass);
return (Handler[])LazyList.toArray(list, byclass);
}
/* ------------------------------------------------------------ */
public <T extends Handler> T getChildHandlerByClass(Class<T> byclass)
{
// TODO this can be more efficient?
Object list = expandChildren(null,byclass);
if (list==null)
return null;
return (T)LazyList.get(list, 0);
}
可以看到都是借助expandChildren()方法来实现的,expandChildren()方法的目的是获取当前handler持有的所有handler对象及这些对象持有的子handler对象,将其加入到传入的list中去,如果传入了byClass参数则只选择那些和byClass类型相符的handler加入。但是这里其实还没有提供一个可以直接使用的实现,需要具体的子类去重写这个方法: