`
234390216
  • 浏览: 10232252 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:462597
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1775446
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1398309
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:394994
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:679961
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:530847
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1183872
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:467783
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:151371
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:68128
社区版块
存档分类
最新评论

通过ServletContainerInitializer注册Servlet对象

阅读更多

通过ServletContainerInitializer注册Servlet对象

Servlet3通过SPI的机制允许我们自定义一个ServletContainerInitializer的实现类,Servlet容器会在启动的时候自动调用实现类的onStartup方法,我们可以在该方法中进行一些Servlet对象的注册。ServletContainerInitializer接口的定义如下:

public interface ServletContainerInitializer {

    public void onStartup(Set<Class<?>> c, ServletContext ctx)
        throws ServletException; 
}

在下面的代码中自定义了一个ServletContainerInitializer的实现类,叫MyServletContainerInitialier。在其onStartup方法中我们通过入参ServletContext分别注册了一个Servlet、一个监听器和一个Filter。

public class MyServletContainerInitializer implements ServletContainerInitializer {

    @Override
    public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
        //注册Servlet
        javax.servlet.ServletRegistration.Dynamic servletRegistration = ctx.addServlet("hello", HelloServlet.class);
        servletRegistration.addMapping("/servlet3/hello");
        servletRegistration.setLoadOnStartup(1);
        servletRegistration.setAsyncSupported(true);
        
        //注册监听器
        ctx.addListener(StartupListener.class);
        
        //注册Filter
        javax.servlet.FilterRegistration.Dynamic filterRegistration = ctx.addFilter("hello", HelloFilter.class);
        filterRegistration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/servlet3/*");
    }

}

它是基于SPI发现的,这需要我们在classpath下面的META-INF/services下新建一个名为javax.servlet.ServletContainerInitializer的文件,然后在里面加上我们自定义的ServletContainerIntializer的全路径名称。如果有多个实现类,每一个实现类写一行。

HandlesTypes

在上面的示例中我们在onStartup的实现中完全没有使用第一个参数classes,它是干什么用的呢?Servlet3允许我们在定义自定义的ServletContainerInitializer的时候通过@HandlesTypes注解指定在自定义的ServletContainerInitializer初始化的时候,也就是调用onStartup时需要自动检测的类型,然后把它们作为onStartup的第一个参数。这在我们搭建框架的时候非常有用,我们可以通过它对外定义一个接口,让有需要通过它来动态注册Servlet对象的人都可以只需要实现我们开放的接口来注册Servlet对象,他们不需要实现完整的ServletContainerInitializer接口,并按照SPI规范在javax.servlet.ServletContainerInitailizer文件中定义。

下面示例中我们通过@HandlesTypes(WebInitializer.class)指定了在容器初始化的时候需要自动检测WebInitializer类型的Class,然后在onStartup方法体中利用反射一一实例化WebInitializer接口实现类,并调用它们的onStartup方法进行Servlet对象的注册。

@HandlesTypes(WebInitializer.class)
public class MyServletContainerInitializer2 implements ServletContainerInitializer {

	@Override
	public void onStartup(Set<Class<?>> classes, ServletContext ctx) 
			throws ServletException {
		// classes就是自动检测到的类路径下的该初始化类上的@HandlesTypes指定的类,
		// 在本示例中就是WebInitializer接口的实现类

		if (classes != null && !classes.isEmpty()) {
			for (Class<?> initializerClass : classes) {
				if (!initializerClass.isInterface() 
						&& !Modifier.isAbstract(initializerClass.getModifiers())) {
					WebInitializer initializer;
					try {
						initializer = (WebInitializer) initializerClass.newInstance();
						initializer.onStartup(ctx);
					} catch (InstantiationException e) {
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

}



public interface WebInitializer {

    void onStartup(ServletContext ctx) throws ServletException; 
    
}

(注:本文是基于Servlet3.1所写,由Elim写于2018年6月23日)

0
0
分享到:
评论

相关推荐

    servlet类库

    此外,它还用于注册监听器、获取其他Servlet或JSP的信息等。 6. **HttpServletRequest和HttpServletResponse接口**:这两个接口分别代表了HTTP请求和响应对象,提供了获取和设置请求头、参数、cookies,以及设置...

    servlet资料API 原版教程 实例

    Servlet通过`HttpServletRequest`和`HttpServletResponse`对象与客户端进行通信。前者封装了请求数据,后者用于构建响应。你可以通过这些对象获取请求参数、头信息,设置响应状态码、内容类型等。 八、实战演练 在...

    Servlet、Filter、Listener深入理解.docx

    4. `ServletContainerInitializer`: 自动注册Servlet和Filter。 通过Servlet、Filter和Listener,开发者可以构建高度定制化的Web应用程序,实现更精细的控制和扩展性。它们共同构成了Java Web应用的基石,帮助...

    Servlet3.1规范(最终版).中文

    开发者可以在应用运行时动态地注册Servlet、Filter和Listener,而无需在web.xml中预先配置。`ServletContainerInitializer`接口用于实现这个功能,允许自定义初始化逻辑。 6. **安全增强**: Servlet3.1提供了更...

    servlet软件开发

    - 动态注册:通过Java代码使用`ServletContainerInitializer`实现Servlet的动态注册。 3. **Servlet容器**: - Tomcat:深入理解Tomcat作为Servlet容器的工作原理。 - Servlet上下文:掌握`ServletContext`对象...

    深入学习JavaServlet开发与实例,搞这块儿的同志下吧

    通过编写实际的Servlet应用,如构建一个简单的CRUD应用,或者实现一个登录注册系统,你可以更好地理解和掌握这些概念。此外,配合阅读提供的"深入学习JavaServlet开发与实例.pdf",结合具体案例分析,将有助于巩固...

    Spring注解驱动开发实战-servlet

    这为开发者提供了在容器启动时进行配置或注册Servlet、Filter和Listener的灵活性,而无需传统的web.xml配置文件。 接下来,我们将关注`ServletContext`,这是Servlet容器的核心组件。在Spring注解驱动的开发中,`...

    Java Web阶段笔试和机试试卷_jsp_servlet.pdf

    这部分主要涉及到四层架构(表现层、业务逻辑层、数据访问层、持久化层)的应用,以及使用Servlet、JSP、Cookie和Filter处理用户注册、登录、删除、修改和查询等操作。对于中文乱码,需要在Filter中设置正确的字符...

    jsp工厂模式jsp工厂模式

    // 注册Servlet工厂 ctx.setInitParameter("jspServletClass", "com.example.MyCustomJspServlet"); } } ``` 在这个例子中,我们使用`setInitParameter`方法将默认的JSPServlet替换为自定义的`...

    Spring MVC总结(一)

    在Servlet 3.0中,提供了多种配置和注册servlet的方式: * 使用web.xml文件(listing 1) * 使用web-fragment.xml文件(listing 2) * 使用javax.servlet.ServletContainerInitializer(listing 3) * 如果使用...

    springboot启动周期流程

    - **注册监听器和Servlet**:将带有WebApplicationInitializer或ServletContainerInitializer接口的类注册为监听器或Servlet。 - **调用ApplicationReadyEvent**:发布此事件,表示应用已经准备就绪,可以开始处理...

    Spring注解驱动开发.pdf

    - **`@Bean`注解**:标记在方法上,表示该方法返回的对象将作为bean注册到Spring容器中。 - **`@Configuration`注解**:标记配置类,表明此类包含一个或多个`@Bean`方法。 ##### 2. Bean的作用域 - **`@Scope`注解...

    SpringBoot启动及自动装配原理过程详解

    Servlet3 规定,如果在当前项目的 classPath 下,存在 META-INF/services/javax.servlet.ServletContainerInitializer 配置文件,且文件中写了 ServletContainerInitializer 的实现类的全类名,容器启动时实现类的 ...

Global site tag (gtag.js) - Google Analytics