ServletContainerInitializer 初始化器

[size=large][b]概述[/b][/size]
[size=medium]为了实现不通过web.xml 启动JavaEE项目,容器提供了javax.servlet.ServletContainerInitializer。第三方的应用需要基于[b]SPI[/b]机制,来实现javax.servlet.ServletContainerInitializer 接口。也就是需要在对应的jar包的META-INF/services 目录创建一个名为javax.servlet.ServletContainerInitializer的文件,文件内容指定具体的ServletContainerInitializer实现类,那么,当web容器启动时就会运行这个初始化器做一些组件内的初始化工作。
一般伴随着ServletContainerInitializer一起使用的还有[b]HandlesTypes[/b]注解,通过HandlesTypes可以将感兴趣的一些类注入到ServletContainerInitializerde的onStartup方法作为参数传入。
[/size]

[size=large][b]自定义实现[/b][/size]
[size=medium]1. 自定义SpringServletContainerInitializer 类[/size]

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {

@Override
public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext ctx) throws ServletException {

List<WebApplicationInitializer> initializers = new LinkedList<>();

if (webAppInitializerClasses != null) {
for (Class<?> waiClass : webAppInitializerClasses) {
// TODO
}
}
}
}

[size=medium]2. 在MEAT-INF中添加实现类信息。[/size]

[img]http://dl2.iteye.com/upload/attachment/0119/5569/0ad4ea8a-89de-3c78-9d6e-6fdaa8c8b72f.png[/img]

[img]http://dl2.iteye.com/upload/attachment/0119/5571/0578475e-b294-3329-a8c2-ae136cb1047c.png[/img]

[size=x-large]
[b]Spring 中的实现[/b]
[/size]
[size=medium]1. 定义实现ServletContainerInitializer的类[/size]

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {

/**
* Delegate the {@code ServletContext} to any {@link WebApplicationInitializer}
* implementations present on the application classpath.
*
* <p>Because this class declares @{@code HandlesTypes(WebApplicationInitializer.class)},
* Servlet 3.0+ containers will automatically scan the classpath for implementations
* of Spring's {@code WebApplicationInitializer} interface and provide the set of all
* such types to the {@code webAppInitializerClasses} parameter of this method.
*
* <p>If no {@code WebApplicationInitializer} implementations are found on the
* classpath, this method is effectively a no-op. An INFO-level log message will be
* issued notifying the user that the {@code ServletContainerInitializer} has indeed
* been invoked but that no {@code WebApplicationInitializer} implementations were
* found.
*
* <p>Assuming that one or more {@code WebApplicationInitializer} types are detected,
* they will be instantiated (and <em>sorted</em> if the @{@link
* org.springframework.core.annotation.Order @Order} annotation is present or
* the {@link org.springframework.core.Ordered Ordered} interface has been
* implemented). Then the {@link WebApplicationInitializer#onStartup(ServletContext)}
* method will be invoked on each instance, delegating the {@code ServletContext} such
* that each instance may register and configure servlets such as Spring's
* {@code DispatcherServlet}, listeners such as Spring's {@code ContextLoaderListener},
* or any other Servlet API componentry such as filters.
*
* @param webAppInitializerClasses all implementations of
* {@link WebApplicationInitializer} found on the application classpath
* @param servletContext the servlet context to be initialized
* @see WebApplicationInitializer#onStartup(ServletContext)
* @see AnnotationAwareOrderComparator
*/
@Override
public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
throws ServletException {

List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>();

if (webAppInitializerClasses != null) {
for (Class<?> waiClass : webAppInitializerClasses) {
// Be defensive: Some servlet containers provide us with invalid classes,
// no matter what @HandlesTypes says...
if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
try {
initializers.add((WebApplicationInitializer) waiClass.newInstance());
}
catch (Throwable ex) {
throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
}
}
}
}

if (initializers.isEmpty()) {
servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
return;
}

AnnotationAwareOrderComparator.sort(initializers);
servletContext.log("Spring WebApplicationInitializers detected on classpath: " + initializers);

for (WebApplicationInitializer initializer : initializers) {
initializer.onStartup(servletContext);
}
}

}



[size=medium]2. META-INF 中添加[/size]

[img]http://dl2.iteye.com/upload/attachment/0119/5569/0ad4ea8a-89de-3c78-9d6e-6fdaa8c8b72f.png[/img]


[img]http://dl2.iteye.com/upload/attachment/0119/5571/0578475e-b294-3329-a8c2-ae136cb1047c.png[/img]

[size=large]
[b]总结[/b]
[/size]
[size=medium]
Spring 提供的SpringServletContainerInitializer 是ServletContainerInitializer 接口真正的实现类,但是Spring另外定义了WebApplicationInitializer 接口作为真正的启动接口,Spring 对该接口的实现都是抽象类,因此在上面方法中过滤时,都被丢弃。

[img]http://dl2.iteye.com/upload/attachment/0119/5579/9407c89d-2ffb-34b8-b42d-ef6c76a851fb.png[/img]

[/size]

[size=large]
[b]引用[/b]
[/size]
[size=medium]
[list]
[*]http://blog.csdn.net/wangyangzhizhou/article/details/52013779
[/list]
[/size]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值