在 Tomcat 部署的啥应用里,我们一般意义上都是然还指普通的应用,大家可以执行的有特用操作等都是一样的,一条起跑线上的啥,没有区别。然还 但对于一些特殊的有特用应用,需要执行一些特别的啥操作,比如官方默认提供的然还 manager应用,可以进行应用的有特用启动、停止、啥部署等一系列操作。然还这些操作的有特用背后,是啥 Tomcat默认包含的 ManagerServlet 实现的, manager 应用实现的然还,是有特用对于该 Servelet 的调用。 那我们自己写一个应用去调用这个 ManagerServlet 不也一样可以吗? 答案是香港云服务器不行的,至少直接操作不行,需要配置。这里就是我们今天提到的 Tomcat 内的特权应用(privileged app)。 manager 应用就是自带的一个特权应用,因此它可以直接调用 ManagerServlet 进行一些容器内部的操作。 我们单独部署的其他应用,就会被限制调用这些容器提供的内部组件,比如一些 Servlet、Filter、Listener。 这些限制资源进行检查时,分为两种类型。 1. 一类是通过类型来进行判断,比如 Servlet 中,ManagerServlet、HTMLManagerServlet 这些都被称为ContainerServlet。实现了相同的接口。 2. 还有一类是在配置文件中指定的,有三个文件: 位于 org.apache.catalina.core 包中。高防服务器 这些内部在 DefaultInstanceManager 初始化时进行解析,例如 servlet的内容解析后是这些: 这些内容也是容器提供的一些功能的实现,比如 GCI 请求处理, JMXProxyServlet 会将 JMX 的属性 dump 出来等等。 特权应用的配置 那怎样能让单独开发的应用成为特权应用,能调用这些容器的功能呢? 之前的文章介绍过应用的部署描述文件context.xml ( Tomcat目录部署与Context描述文件context.xml),这次我们的升级特权操作也是需要在这里进行。 具体来说,在应用部署时,将应用的 Context 对象中 privileged属性设置为 true。例如 manager 应用的配置是这样的,文件位于于 manager 的META-INF 目录中,单独开发时可以参考: 这样配置之后,在应用部署时就会将代表应用的 StandardContext 对象中 privileged 属性设置为true,服务器托管后面会读取使用。 特权应用的工作原理 应用在启动时,会将 DefaultInstanceManager 做为其 instanceManager。该属性在后面 Servlet、Filter、Listener 这些组件加载时使用,做为实例管理器,进行 newInstance的管理。 以 Servlet 为例,有些 loadOnStartup 的 Servlet,会在部署启动应用时直接生成实例。 在 loadServlet 阶段时,会先通过 Wrapper 获取父容器 Context 的 instanceManager,再通过 instanceManager 来加载具体的 Servlet class。 以下为 instanceManager 进行 newInstace 时的逻辑 在loadClassMaybePrivileged中,对于catalina包中的 class,会使用ServerClassLoader 来进行加载,除了通过不同的classLoader加载外,还会进行上面说的 privileged 检查。 对于 priviledged 应用,之后的 checkAccess 就直接跳过,否则会判断是否是 ContainerServlet,是否在配置文件中进行限制等,只有都检查通过才可以进行 使用。 例如 普通的应用在使用HTMLManagerServlet ,此时由于限制检查,会提示500。 所以,之后有需要使用容器提供的功能时,可以将应用升级为特权应用,然后调用容器提供的高级功能。 【本文为专栏作者“侯树成”的原创稿件,转载请通过作者微信公众号『Tomcat那些事儿』获取授权】 戳这里,看该作者更多好文