在Tomcart中Container是處理web應用中對servlet request和response對象的請求。有四種容器,Engine, Host, Context, and Wrapper.下面是類圖
1.Engine. Represents the entire Catalina servlet engine.
2.Host. Represents a virtual host with a number of contexts.
3.Context. Represents a web application. A context contains one or more.
4. Wrapper. Represents an individual servlet.
一般一個容器可以有多個子容器
public void addChild(Container child);
public void removeChild(Container child);
但是wrapper不能有子容器,如果調用addChild會拋出IllegalStateException
public void addChild(Container child) {
throw new IllegalStateException
(sm.getString("standardWrapper.notChild"));
}
容器提供了查找子容器的方法
public Container findChild(String name);
public Container[] findChildren();
當我們調用servlet的時候,要經過Pipelining,那麼這個Pipelining有什麼用呢?其實它就想servlet的filter chain,那麼它肯定就有filter了,那就是valve,下面是pipe的類圖
public interface Valve {
//-------------------------------------------------------------- Properties
/**
* Return descriptive information about this Valve implementation.
*/
public String getInfo();
/**
* Return the next Valve in the pipeline containing this Valve, if any.
*/
public Valve getNext();
/**
* Set the next Valve in the pipeline containing this Valve.
*
* @param valve The new next valve, or <code>null</code> if none
*/
public void setNext(Valve valve);
//---------------------------------------------------------- Public Methods
/**
* Execute a periodic task, such as reloading, etc. This method will be
* invoked inside the classloading context of this container. Unexpected
* throwables will be caught and logged.
*/
public void backgroundProcess();
public void invoke(Request request, Response response)
throws IOException, ServletException;
/**
* Process a Comet event.
*
* @param request The servlet request to be processed
* @param response The servlet response to be created
*
* @exception IOException if an input/output error occurs, or is thrown
* by a subsequently invoked Valve, Filter, or Servlet
* @exception ServletException if a servlet error occurs, or is thrown
* by a subsequently invoked Valve, Filter, or Servlet
*/
public void event(Request request, Response response, CometEvent event)
throws IOException, ServletException;
}
當我們往pipeline添加valve時,只要調用
public void addValve(Valve valve);
那麼container是怎麼調用valve的invoke呢
在ContainerBase實現Pipeline接口,
public void invoke(Request request, Response response)
throws IOException, ServletException {
pipeline.getFirst().invoke(request, response);
}
在valve的實現類中,我們看到
public void invoke(Request request, Response response)
throws IOException, ServletException {
//do something you want.....
getNext().invoke(request, response);
}
這樣valve在pipe好像組成一個鏈條一樣,第一個調用完,再調用第二個,一直到完爲止。不過要調用一個默認的valve,之後的才能調用
其實tomcat爲四個容器都提供個默認的valve。StandardContextValve、StandardEngineValve、StandardHostValve、StandardWrapperValve。
這裏的Contained接口是保證你這個對象最多隻屬於一個容器
public interface Contained {
//-------------------------------------------------------------- Properties
/**
* Return the <code>Container</code> with which this instance is associated
* (if any); otherwise return <code>null</code>.
*/
public Container getContainer();
/**
* Set the <code>Container</code> with which this instance is associated.
*
* @param container The Container instance with which this instance is to
* be associated, or <code>null</code> to disassociate this instance
* from any Container
*/
public void setContainer(Container container);
}
其實你也可以自定製valve然後在server.xml配置。
一個container可以有一些附加的組件,已有的組件有
- Loader - Class loader to use for integrating new Java classes for this Container into the JVM in which Catalina is running.
- Logger - Implementation of the
log()
method signatures of theServletContext
interface. - Manager - Manager for the pool of Sessions associated with this Container.
- Realm - Read-only interface to a security domain, for authenticating user identities and their corresponding roles.
- Resources - JNDI directory context enabling access to static resources, enabling custom linkages to existing server components when Catalina is embedded in a larger server.