spring框架的WebApplicationInitializer接口

来源:互联网 发布:树莓派3b ubuntu mate 编辑:程序博客网 时间:2024/06/12 01:41

疑问:为什么实现了WebApplicationInitializer接口的类,在自动时会自动执行其重写的onStart()方法?

第一步: 查看接口WebApplicationInitializer的API(spring-web-x.x.x.jar下),该接口只有一个方法:
void onStartup(ServletContext servletContext) throws ServletException;

接口说明:

Interface to be implemented in Servlet 3.0+ environments in order to configure the ServletContext programmatically – as opposed to (or possibly in conjunction with) the traditional web.xml-based approach.
Implementations of this SPI will be detected automatically by SpringServletContainerInitializer, which itself is bootstrapped automatically by any Servlet 3.0 container.

翻译过来,实现该接口可以在Servlet 3.0 +环境中以编程方式配置ServletContext,而不是(或结合)传统的基于web.xml文件配置。实现由SpringServletContainerInitializer SPI将自动检测到,这本身就是由任何Servlet 3.0容器自动引导。

第二步:查看类SpringServletContainerInitializer的API(同包下),该类实现了ServletContainerInitializer接口,重写了其void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException;方法

其方法代码如下:

@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);        }    }

类说明:

This class will be loaded and instantiated and have its onStartup(java.util.Set, javax.servlet.ServletContext) method invoked by any Servlet 3.0-compliant container during container startup assuming that the spring-web module JAR is present on the classpath. This occurs through the JAR Services API ServiceLoader.load(Class) method detecting the spring-web module’s META-INF/services/javax.servlet.ServletContainerInitializer service provider configuration file. See the JAR Services API documentation as well as section 8.2.4 of the Servlet 3.0 Final Draft specification for complete details.

翻译过来,这个类将被加载和实例化,其 onStartup(java.util.Set<java.lang.Class<?>>, javax.servlet.ServletContext)方法在任何Servlet 3.0兼容的容器在容器启动时被调用,当JAR的spring-web模块存在的classpath中。在当JAR服务APIServiceLoader.load(Class)方法检测spring-web模块的META-INF/services/javax.servlet.ServletContainerInitializer`服务提供者配置文件时发生。请参见JAR服务API文档以及部分8.2.4 Servlet 3.0的最终草案规范完整的细节。

1 0
原创粉丝点击