你們應該都已經知道Spring 3.1對無web.xml式基於代碼配置的servlet3.0應用。經過spring的api或是網絡上高手們的博文,也必定很快就學會而且加到本身的應用中去了。PS:若是還沒,也能夠小小參考一下鄙人的上一篇文章<<探 Spring 3.1之無web.xml式 基於代碼配置的servlet3.0應用>>。
通過一天的深度research, 我瞭解,理解以及重現了springframework的那一小段代碼。
OK,第一步,入手點,WebApplicationInitializer接口。由於咱們只需實現這個接口覆寫它的一個方法,就能夠作到配置web.xml一樣的功效。看它的源碼,其實看和不看沒什麼兩樣: java
package org.springframework.web; import javax.servlet.ServletContext; import javax.servlet.ServletException; public interface WebApplicationInitializer { void onStartup(ServletContext servletContext) throws ServletException; }
就這麼點兒,有效代碼5行,弄地我一頭霧水,就是一個普通接口,聲明瞭一個方法。連註解都沒有,server是怎麼找到實現了它的類的?若是這樣,何不找我定義的其它接口(的實現類完成配置工做)呢。可見如今java的解耦技術,真使人汗顏。
第二步,這個接口旁邊(同包)有個SpringServletContainerInitializer, 看下它是何方神聖吧:web
package org.springframework.web; import java.lang.reflect.Modifier; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.ServiceLoader; import java.util.Set; import javax.servlet.ServletContainerInitializer; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.HandlesTypes; import org.springframework.core.annotation.AnnotationAwareOrderComparator; @HandlesTypes(WebApplicationInitializer.class) public class SpringServletContainerInitializer implements ServletContainerInitializer { 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; } Collections.sort(initializers, new AnnotationAwareOrderComparator()); servletContext.log("Spring WebApplicationInitializers detected on classpath: " + initializers); for (WebApplicationInitializer initializer : initializers) { initializer.onStartup(servletContext); } } }