Spring-web源碼解析之Initializer2-SpringServletContainerInitializer

基於4.1.7.RELEASE

ServletContainerInitializer

前面都是Spring內部WebApplicationInitializer的實現,下面來看一個Servlet包中ServletContainerInitializer的實現。

首先看類申明

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

出現了一個@HandlesTypes的註解,這個註解的作用是指明在ServletContainerInitializer的實現類中其onStartup方法中所傳進來的Class類型。

onStart的方法主要是創建WebApplicationInitializer並進行調用。

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

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

   if (webAppInitializerClasses != null) {
      for (Class<?> waiClass : webAppInitializerClasses) {
         if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
               WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
            try {
               initializers.add((WebApplicationInitializer) waiClass.newInstance());
            }catch (Throwable ex) {
            }
         }
      }
   }

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

在上面的代碼中,首先進行了WebApplicationInitializer的實例化工作,爲什麼waiClass.newInstance()能夠生效呢,是因爲Servlet(3.0+)的容器在啓動時掃描了所有@HandlesTypes指定的Class的實現類,然後封裝在webAppInitializerClasses的Set裏傳遞進來。

初始化完畢之後對所有的initializers進行了排序,如果initializer有@Order註解或者實現了Order接口,那麼排序會依照Order指定的順序完成。

排序之後則是調用了所有的initializer的onStartup方法,這些方法裏或初始化DispatchServlet,或ConextLoaderListener,或Filter則根據各類不同的實現規則而定,由此可以看出Spring初始化的一些端倪。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章