在Tomcat中,每个HTTP请求都会通过一系列阶段(Phase)来处理。这些阶段由 Pipeline 组织起来。
Tomcat Pipeline 由多个 Valve 组成,每个 Valve 对应一个阶段。请求在每个阶段中都会执行相应的 valve。
Tomcat 默认 Pipeline 中包含了以下几个重要的 Valve:
AccessLogValve:用于记录访问日志。
StandardEngineValve:处理 HTTP 请求并将其发送到连接器。
StandardHostValve:相关到主机配置,如虚拟主机设置等。
StandardContextValve:与应用程序的上下文环境相关,如类加载、安全控制等。
StandardWrapperValve:与具体的 Servlet 相关,执行 Servlet 生命周期并进行 Servlet 调用。
这些 Valve 按顺序执行,组成了 Tomcat 的 Pipeline。请求在进入 Tomcat 后,会依次通过每个 Valve 的处理。
Pipeline 的优点是可以向 Tomcat 增加新的功能模块,只需定义一个新的 Valve 并插入到 Pipeline 的合适位置即可。
例如,我们可以定义一个安全检查 Valve,放在 StandardContextValve 后面,实现在 Servlet 执行前进行安全检查。
此外,每个 Valve 都可以选择不处理请求而直接传给下一个 Valve。这提供了很大的灵活性。
通过 Pipeline 机制,Tomcat 将处理请求的流程模块化并使其开放易扩展,这是 Tomcat 设计中一个重要的概念。
javapublic interface Pipeline extends Contained {
/**
* @return the Valve instance that has been distinguished as the basic
* Valve for this Pipeline (if any).
*/
Valve getBasic();
/**
* <p>Set the Valve instance that has been distinguished as the basic
* Valve for this Pipeline (if any). Prior to setting the basic Valve,
* the Valve's <code>setContainer()</code> will be called, if it
* implements <code>Contained</code>, with the owning Container as an
* argument. The method may throw an <code>IllegalArgumentException</code>
* if this Valve chooses not to be associated with this Container, or
* <code>IllegalStateException</code> if it is already associated with
* a different Container.</p>
*
* @param valve Valve to be distinguished as the basic Valve
*/
void setBasic(Valve valve);
/**
* <p>Add a new Valve to the end of the pipeline associated with this
* Container. Prior to adding the Valve, the Valve's
* <code>setContainer()</code> method will be called, if it implements
* <code>Contained</code>, with the owning Container as an argument.
* The method may throw an
* <code>IllegalArgumentException</code> if this Valve chooses not to
* be associated with this Container, or <code>IllegalStateException</code>
* if it is already associated with a different Container.</p>
*
* <p>Implementation note: Implementations are expected to trigger the
* {@link Container#ADD_VALVE_EVENT} for the associated container if this
* call is successful.</p>
*
* @param valve Valve to be added
*
* @exception IllegalArgumentException if this Container refused to
* accept the specified Valve
* @exception IllegalArgumentException if the specified Valve refuses to be
* associated with this Container
* @exception IllegalStateException if the specified Valve is already
* associated with a different Container
*/
void addValve(Valve valve);
/**
* @return the set of Valves in the pipeline associated with this
* Container, including the basic Valve (if any). If there are no
* such Valves, a zero-length array is returned.
*/
Valve[] getValves();
/**
* Remove the specified Valve from the pipeline associated with this
* Container, if it is found; otherwise, do nothing. If the Valve is
* found and removed, the Valve's <code>setContainer(null)</code> method
* will be called if it implements <code>Contained</code>.
*
* <p>Implementation note: Implementations are expected to trigger the
* {@link Container#REMOVE_VALVE_EVENT} for the associated container if this
* call is successful.</p>
*
* @param valve Valve to be removed
*/
void removeValve(Valve valve);
/**
* @return the Valve instance that has been distinguished as the basic
* Valve for this Pipeline (if any).
*/
Valve getFirst();
/**
* Returns true if all the valves in this pipeline support async, false otherwise
* @return true if all the valves in this pipeline support async, false otherwise
*/
boolean isAsyncSupported();
/**
* Identifies the Valves, if any, in this Pipeline that do not support
* async.
*
* @param result The Set to which the fully qualified class names of each
* Valve in this Pipeline that does not support async will be
* added
*/
void findNonAsyncValves(Set<String> result);
}
本文作者:yowayimono
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!