动态加载机Servlet容器加载器
动态加载是Servlet 3.0中的新特性,它可以实现在 不重启Web应用的情况下加载新的Web对象(Servlet、 Filter、Listener)。Servlet容器加载器也是Servlet 3.0中 的新特性,对于框架的开发者来说特别有用。
一.动态加载
为了实现动态加载,ServletContext接口中增加了如 下方法,用于动态创建Web对象:
<T extends Filter> createFilter(java.lang.Class<T> clazz)
<T extends java.util.EventListener> createListener(java.lang.Class<T> clazz)
<T extends Servlet> createServlet(java.lang.Class<T> clazz)
例如,如果MyServlet是一个直接或者间接继承 javax.servlet.Servlet的类,那么就可以通过createServlet 的方法初始化它:
Servlet myServlet = createServlet(MyServlet.class);
在创建了Web对象后,可以通过ServletContext中如 下的方法把它注册到ServletContext中(这也Servlet 3中 的新特性):
FilterRegistration.Dynamic addFilter(java.lang.String filterName,Filter filter)
<T extends java.util.EventListener> void addListener(T t)
ServletRegistration.Dynamic addServlet(java.lang.String servletName, Servlet servlet)
也可以使用ServletContext中的如下方法,创建Web 对象并把这个Web对象加入到ServletContext中:
FilterRegistration.Dynamic addFilter(java.lang.String filterName,
java.lang.Class<? extends Filter> filterClass)
FilterRegistration.Dynamic addFilter(java.lang.String filterName,
java.lang.String className)
void addListener(java.lang.Class<? extends java.util.EventListener> listenerClass)
void addListener(java.lang.String className)
ServletRegistration.Dynamic addServlet(java.lang.String
servletName, java.lang.String className)
ServletRegistration.Dynamic addServlet(java.lang.String
servletName, java.lang.String className)
要创建或者增加Listener,传递给第一个addListener 方法的类需要实现以下的一个或者多个接口:
- ServletContextAttributeListener
- ServletRequestListener
- ServletRequestAttributeListener
- HttpSessionListener
- HttpSessionAttributeListener
如果ServletContext是用于ServletContextInitializer中 onStartup方法的参数,那么Listener也需要实现 ServletContextListener。关于startUp方法以及 ServletContextInitializer接口更多的信息
addFilter及addServlet的方法返回值为 FilterRegistration.Dynamic及ServletRegistration. Dynamic。
FilterRegistration.Dynamic及 ServletRegistration.Dynamic都是Registration.Dynamic的 子接口。FilterRegistration.Dynamic允许配置Filter,而 ServletRegistration.Dynamic则允许配置Servlet。
举个例子,在app14a应用中包含了名为FirstServlet 的Servlet以及一个名为DynRegListener的Listener。这个 Servlet没有使用@WebServlet的注解,也没有使用部署 描述来声明它,而通过Listener来注册这个动态的 Servlet并让它生效 。
FirstServlet类
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class FirstServlet extends HttpServlet {
private static final long serialVersionUID = -6045338L;
private String name; @Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.println("<html><head><title>First servlet" + "</title></head><body>" + name);
writer.println("</body></head>");
} public void setName(String name) {
this.name = name;
}
}
DynRegListener类
package listener; import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRegistration;
import javax.servlet.annotation.WebListener;
import servlet.FirstServlet; @WebListener
public class DynRegListener implements ServletContextListener{
@Override
public void contextDestroyed(ServletContextEvent sce) { }
// use createServlet to obtain a Servlet instance that canbe
// configured prior to being added to ServletContext
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
Servlet firstServlet = null;
try {
firstServlet = servletContext.createServlet(FirstServlet.class);
}catch(Exception e){
e.printStackTrace();
}
if(firstServlet!=null && firstServlet instanceof FirstServlet) {
(( FirstServlet)firstServlet).setName("Dynamically reigistered servlet");
}
// the servlet may not be annotated with @WebServlet
ServletRegistration.Dynamic dynamic = servletContext.addServlet("firstServlet", firstServlet);
dynamic.addMapping("/firstServlet");
}
}

二.Servlet容器加载器
如果使用Java Web框架,如Struts、Struts 2,则需 要在使用该框架前先对应用进行配置。典型的例子是, 通过修改部署描述来告诉Servlet容器你在使用某个框 架。例如,在应用中使用Struts 2,就要加入如下的标 签到部署描述中:
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.
➥ StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/ *</url-pattern>
</filter-mapping>
在Servlet 3中,这个步骤可以省略了。框架打包时 使用这种方法,就可以对这些Web对象实现自动初始化 了。
Servlet容器初始化主要是通过 javax.servlet.ServletContainerInitializer这个接口。这个接 口很简单,只有一个方法:onStartup。Servlet容器中, 这个方法在任何ServletContext Litener初始化前都可能 会被调用到。
Servlet容器初始化主要是通过 javax.servlet.ServletContainerInitializer这个接口。这个接 口很简单,只有一个方法:onStartup。Servlet容器中, 这个方法在任何ServletContext Litener初始化前都可能 会被调用到。 onStartup的定义如下
void onStartup(java.util.Set<java.lang.Class<?>> klazz,
ServletContext servletContext)
举个例子,本书中的initializer.jar包就包含了Servlet 容器加载器,用于注册名为UserfulServlet的Servlet。图 中列出了initializer.jar的结构。

这个库是一种插件化的框架。其中有两个重要的资 源:initializer类(如清单14.3中列出来的 initializer.MyServletContainerInitializer)以及名为 javax.servlet.ServletContainerInitializer的元文件。这个元 文件必须放在JAR包中的META-INF/services目录下。 如清单14.3所示,这个文件只有一行: ServletContainerInitializer的实现类名。
ServletContainerInitializer
package initializer;
import java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.annotation.HandlesTypes;
import servlet.UsefulServlet;
@HandlesTypes({UsefulServlet.class})
public class MyServletContainerInitializer implements
ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> classes, ServletContext
servletContext) throws ServletException {
System.out.println("onStartup");
ServletRegistration registration =
servletContext.addServlet("usefulServlet",
"servlet.UsefulServlet");
registration.addMapping("/useful");
System.out.println("leaving onStartup");
}
}
清单 javax.servlet.ServletContainerInitializer文件
initializer.MyServletContainerInitializer
MyServletContainerInitializer中onStartup方法的主要 任务就是注册Web对象。这个例子中,只有一个名为 UsefulServlet的Servlet对象,并绑定到/useful的路径 中。在大型框架中,注册结构可以是像Struts或者Struts 2这样的XML文档。
????????????????????????????????????????没搞明白
动态加载机Servlet容器加载器的更多相关文章
- 动态加载及Servlet容器加载
动态加载 动态加载是 Servlet 3.0 中的新特性,它可以实现在不重启 Web 应用的情况下加载新的 Web 对象(Servlet.Filter.Listener). 为了实现动态加载的第一种方 ...
- 对于Servlet、Servlet容器以及一个Servlet容器-Tomcat
Servlet.Servlet容器等内容讲解 转载自http://blog.csdn.net/iAm333 对于Servlet.Servlet容器以及一个Servlet容器-Tomcat这些概念讲解的 ...
- Servlet、Servlet容器等内容讲解
转载自http://blog.csdn.net/iAm333 对于Servlet.Servlet容器以及一个Servlet容器-Tomcat这些概念讲解的挺清晰的,转载下 之前在开源中国看到一篇文章& ...
- java框架之SpringBoot(8)-嵌入式Servlet容器
前言 SpringBoot 默认使用的嵌入式 Servlet 容器为 Tomcat,通过依赖关系就可以看到: 问题: 如何定制和修改 Servlet 容器相关配置? SpringBoot 能否支持其它 ...
- 配置Servlet 容器
SpringBoot默认使用Tomcat作为嵌入式的Servlet容器: 1.如何定制和修改Servlet容器的相关配置: 1.修改和server有关的配置(ServerProperties[也是Em ...
- SpringBoot(七) -- 嵌入式Servlet容器
一.嵌入式Servlet容器 在传统的开发中,我们在完成开发后需要将项目打成war包,在外部配置好TomCat容器,而这个TomCat就是Servlet容器.在使用SpringBoot开发时,我们无需 ...
- SpringBoot配置嵌入式Servlet容器
1).如何定制和修改Servlet容器的相关配置: 1.修改和server有关的配置(ServerProperties[也是EmbeddedServletContainerCustomizer]): ...
- servlet容器处理请求过程
下图是关于tomcat服务器接收客户请求并作出响应的图例. tomcat不仅仅只是一个servlet容器,也是一个web服务器,servlet容器在web服务器之内或者说servlet容器托管于web ...
- 过滤器(servlet.filter)和拦截器(springmvc.interceptor)区别
①拦截器是基于java的反射机制的,而过滤器是基于函数回调. ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器. ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求 ...
随机推荐
- Python——Twisted框架(网络通信)
一.简介 twisted是一个封装好的网络通信的库,可以帮助我们快速进行网络编程.注意,python3中,字符串必须转码成utf8的格式,否则无法发送.比如str("test"). ...
- python 基本数据类型以及运算符操作
一.基本数据类型 为何要区分类型? 数据类型的值是变量值得类型,变量值之所以区分类型,是因为变量的值 用来记录事物的状态,而事物的状态有不同的种类,对应着,也必须用不 用类型去区分它们. 1.数字类型 ...
- vhdl 数组
TYPE matrix_index is array (511 downto 0) of std_logic_vector(7 downto 0);signal cnt_freq : matrix_i ...
- [模板] k短路
简介 Dijkstra最短路+A*搜索. 先逆向求所有点到终点的最短路 \(dis[i]\). 定义估价函数 \(f[i] = d[i] + dis[i]\) , 其中 \(d[i]\) 表示当前起点 ...
- 【nowcoder-2017校招真题】保留最大的数
牛客在线编程-保留最大的数 题目描述 给定一个十进制的正整数number,选择从里面去掉一部分数字,希望保留下来的数字组成的正整数最大. 输入描述: 输入为两行内容,第一行是正整数number,1 ≤ ...
- 联想的笔记本有隐藏分区 导致无法安装win10 eufi启动 报错:windows无法更新计算机的启动配置。无法安装
联想的笔记本都带着类似一键还原等的系统恢复软件,这些软件往往是将出厂设置备份在单 独的一个分区,此分区默认为隐藏,在 Windows 的磁盘管理中可以看到.打开磁盘管理器 的方法是右击计算机——管理, ...
- OpenLayers学习笔记(八)— 类似比例尺的距离环(二)
openlayers 3 地图上创建一个距离环,始终以地图中心为中心,每个环之间的距离类似比例尺,随地图缩放而变化. 添加具有覆盖整个范围的特征的虚拟层,其可以被设置为围绕地图中心的环. 这篇是上一篇 ...
- go Test的实现 以及 压力测试
引用 import "testing" 一些原则 文件名必须是 *_test.go* 结尾的,这样在执行 go test 的时候才会执行到相应的代码 必须 import testi ...
- 洛谷P2120 [ZJOI2007]仓库建设 斜率优化DP
做的第一道斜率优化\(DP\)QwQ 原题链接1/原题链接2 首先考虑\(O(n^2)\)的做法:设\(f[i]\)表示在\(i\)处建仓库的最小费用,则有转移方程: \(f[i]=min\{f[j] ...
- SQL学习指南第二篇
使用集合 union操作符(组合查询) 多数 SQL 查询只包含从一个或多个表中返回数据的单条 SELECT 语句.但是,SQL 也允许执行多个查询(多条 SELECT 语句),并将结果作为一个查询结 ...