动态加载及Servlet容器加载
动态加载
动态加载是 Servlet 3.0 中的新特性,它可以实现在不重启 Web 应用的情况下加载新的 Web 对象(Servlet、Filter、Listener)。
为了实现动态加载的第一种方式:创建 Web 对象和注册 Web 对象到 ServletContext 中分步进行
ServletContext 接口增加了如下方法,用于动态创建 Web 对象:
<T extends Servlet> T createServlet(java.lang.Class<T> c) throws ServletException //
<T extends Filter> T createFilter(java.lang.Class<T> c) throws ServletException //
<T extends java.util.EventListener> T createListener(java.lang.Class<T> c) throws ServletException //
例如,如果MyServlet是一个直接或者间接继承 javax.servlet.Servlet 的类,那么就可以通过 createServlet 的方法初始化它:
Servlet myServlet = servletContext.createServlet(MyServlet.class); // 这里使用了反射技术
在创建了 Web 对象之后,可以通过 ServletContext 中的如下方法把它注册到 ServletContext 中
ServletRegistration.Dynamic addServlet(java.lang.String servletName, Servlet servlet) //
FilterRegistration.Dynamic addFilter(java.lang.String filterName, Filter filter) //
<T extends java.util.EventListener> void addListener(T t) //
实现动态加载的第二种方式:创建 Web 对象和注册 Web 对象到 ServletContext 中一步完成
使用 ServletContext 中的如下方法
ServletRegistration.Dynamic addServlet(java.lang.String servletName, java.lang.Class<? extends Servlet> servletClass)
ServletRegistration.Dynamic addServlet(java.lang.String servletName, java.lang.String className) 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)
要创建或者增加Listener,传递给第一个 addListener 方法的类需要实现以下的一个或者多个接口
ServletContextAttributeListener
ServletRequestListener
ServletRequestAttributeListener
HttpSessionListener
HttpSessionAttributeListener
如果 ServletContext 是用于 ServletContextInitializer 中的 onStartup 方法的参数,那么 Listener 也需要实现 ServletContextListener
动态加载实例
package app14a.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 { // 一个 Servlet,该 Servlet 没有使用 @WebServlet 注解,也没有使用部署描述符来声明。
private static final long serialVersionUID = 1L; // 而是通过使用 Listener 来动态创建、注册、绑定这个 Servlet 并让其生效的。
private String name; public void setName(String name) {
this.name = name;
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<head>");
writer.println("<title>First Servlet</title>");
writer.println("</head>");
writer.println("<body>");
writer.println(name);
writer.println("</body>");
writer.println("</html>");
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
package app14a.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 app14a.servlet.FirstServlet; @WebListener // 注解
public class DynRegListener implements ServletContextListener { // 监听器 @Override
public void contextInitialized(ServletContextEvent sce) { // ServletContext 创建时,容器调用该方法
ServletContext servletContext = sce.getServletContext(); // 获取 ServletContext 对象实例
Servlet firstServlet = null;
try {
firstServlet = servletContext.createServlet(FirstServlet.class); // 动态创建 Web 对象
} catch (Exception e) {
e.printStackTrace();
}
if (firstServlet != null && firstServlet instanceof FirstServlet) {
((FirstServlet) firstServlet).setName("Dynamically registered servlet");
}
ServletRegistration.Dynamic dynamic = servletContext.addServlet("firstServlet", firstServlet); // 注册到 ServletContext 中
dynamic.addMapping("/dynamic"); // 绑定路径
} @Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
测试结果,Servlet 成功注册到了 ServletContext 中,且绑定到 /dynamic 路径
Servlet容器加载
Servlet 容器加载器也是 Servlet 3.0 中的新特性,对于框架的开发者来说特别有用。
Servlet 容器初始化主要是通过 javax.servlet.ServletContainerInitializer 这个接口。该接口只有一个方法 onStartup。
Servlet 容器中,这个方法在任何 ServletContext 的 Listener 初始化之前都可能会被调用到。
void onStartup(java.util.Set<java.lang.Class<?>> c, ServletContext ctx) throws ServletException //
ServletContainerInitializer 的实现类必须使用 HandleTypes 的注解,以便让加载器能够识别。
package app14a.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}) // ServletContainerInitializer 的实现类必须使用该注解
public class MyServletContainerInitializer implements ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> classes, ServletContext servletContext) throws ServletException { // 该方法的主要任务就是注册 Web 对象
System.out.println("onStartup");
ServletRegistration registration = servletContext.addServlet("usefulServlet", "servlet.UsefulServlet"); // 创建并注册
registration.addMapping("/useful"); // 绑定访问路径
System.out.println("leaving onStartup");
}
}
插件(即 initializer.jar)中的内容
测试结果,
动态加载及Servlet容器加载的更多相关文章
- 动态加载机Servlet容器加载器
动态加载是Servlet 3.0中的新特性,它可以实现在 不重启Web应用的情况下加载新的Web对象(Servlet. Filter.Listener).Servlet容器加载器也是Servlet 3 ...
- 对于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网络编程基本功之Servlet与Servlet容器
Servlet与Servlet容器关系 Servlet 比较这两个的区别, 就得先搞清楚Servlet 的含义, Servlet (/ˈsərvlit/ ) 翻译成中文就是小型应用程序或者小服务程序, ...
- servlet容器处理请求过程
下图是关于tomcat服务器接收客户请求并作出响应的图例. tomcat不仅仅只是一个servlet容器,也是一个web服务器,servlet容器在web服务器之内或者说servlet容器托管于web ...
- servlet 启动加载配置文件及初始化
在servlet开发中,会涉及到一些xml数据的读取和一些初始化方法的调用.可以在tomcat启动的时候,加载一个servlet去初始化一些数据. 摘自 http://stone02111.iteye ...
- springMVC容器加载源码分析
springmvc是一个基于servlet容器的轻量灵活的mvc框架,在它整个请求过程中,为了能够灵活定制各种需求,所以提供了一系列的组件完成整个请求的映射,响应等等处理.这里我们来分析下spring ...
- web应用启动的时候SpringMVC容器加载过程
<!-- 配置DispatcherServlet --> <servlet> <servlet-name>springmvc</servlet-name> ...
- web.xml中配置启动时加载的servlet,load-on-starup
web.xml中配置启动时加载的servlet,load-on-starup 使用servlet来初始化配置文件数据: 在servlet的配置当中,<load-on-startup>1&l ...
随机推荐
- linux投递运行情况
1.构建文件夹 ..}.sh 2.状态 D 不可中断 Uninterruptible sleep (usually IO) R 正在运行,或在队列中的进程 S 处于休眠状态 T 停止或被追踪 Z 僵尸 ...
- 1.5.7、CDH 搭建Hadoop在安装之前(定制安装解决方案---配置单用户模式)
配置单用户模式 在传统的Cloudera Manager部署中,管理每台主机上的Hadoop进程的Cloudera Manager Agent以root用户身份运行.但是,某些环境会限制对root帐户 ...
- V4 V7 V13支持包的区别(转)
三者均为支持包,可以让低版本系统使用高版本特性,支持最小版本有差异 V4支持1.6以上 V7支持2.1以上 V13支持3.2以上 V7依赖V4 转自:
- ssh 与远程机器保持心跳(linux)
文件/etc/ssh/ssh_config末尾加上: TCPKeepAlive yes ServerAliveInterval
- Django的几种缓存的配置
1.缓存的简介 在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面. 当一个网站的用户访问量很大的时候,每一次的的后台操作,都会 ...
- ASP.Net MVC 中a标签的onclick时间和href同时存在时候的处理
问题出现: 本次项目在用到下载文件.导出文件的时候,需要在下载.导出之前进行判断,最初使用方式一.二,没能解决问题 方式一:使用href直接跳转controller方法,以下载为例: public A ...
- stm32GPIO的8种工作模式
推挽输出:可以输出高.低电平,连接数字器件:推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止.高低电平由IC的电源决定. 推挽电路是两个参数相同的三极管或MOS ...
- [转]Docker到底是什么?为什么它这么火?
如果你是数据中心或云计算IT圈子的人,这一年多来应该一直在听到普通的容器.尤其是Docker,关于它们的新闻从未间断过.Docker1.0在今年6月发布后,声势更是达到了前所未有的程度. 动静之所以这 ...
- f5电源模块损坏
现象: ssh登录f5后有日志显示 现场确认f5 2槽电源指示灯不亮,且电源线正常.重新开关电源模块,拔插电源线后仍不亮.故确认是电源模块损坏. 处理:直接采购新的电源模块更换即可.f5电源支持热插拔 ...
- OC 开发规范指南 - 个人见解写的很好
纽约时报 移动团队 Objective-C 规范指南 这份规范指南概括了纽约时报 iOS 团队的代码约定. 介绍 关于这个编程语言的所有规范,如果这里没有写到,那就在苹果的文档里: • Objecti ...