搭建SpringMVC除了通过部署描述文件的形式还可以采用Java类配置的形式。从Servlet3.0之后,Servlet容器会在应用的类路径中查找javax.servlet.ServletContainerInitializer接口的实现类。而SpringMVC提供了这个接口的实现类SpringServletContainerInitializer。Servlet容器会自动的调用这个实现类的onStartup方法,对于SpringMVC提供的实现类,它的onStartup方法具体实现,又将对ServletContext进行配置的任务交给WebApplicationInitializer接口的实现类。该接口同样由SpringMVC提供。
在采用部署描述文件,即web.xml,是通过在这个文件中添加Servlet、Listener、Filter等来完成的对ServletContext的配置。现在转向在WebApplicationInitializer接口的实现类来完成这一任务了。接口WebApplicationInitializer只有一个抽象方法:
接口WebApplicationInitializer的实现类正是通过传入参数列表的servletContext来完成对ServletContext的配置。ServletContext代表了一个应用在Servlet容器里运行的上下文环境。
总结: SpringMVC提供了SpringServletContainerInitializer类,使得Servlet容器能自动的发现它,并调用的它的onStartup方法,该方法又去查找WebApplicationInitializer实现类,并调用实现类的onStartup方法。为了便于搭建SpringMVC,额外提供了一些抽象类。
AbstractContextLoaderInitializer抽象类实现WebApplicationInitializer接口。
AbstractContextLoadInitializer抽象类还定义了creatRootApplicationContext方法,ApplicationContext是对Spring IoC 容器的抽象表示。可以看到这个方式是抽象方法,交给它的子类来选择以哪种方式实现ApplicationContext。此外还定义了registerContextLoader方法,正是在这个方法里,向ServletContext注册了监听器org.springframework.web.context.ContextLoaderListener。当采用web.xml部署描述文件搭建SpringMVC时,也会看到注册了这个监听器。到AbstractContextLoadInitializer抽象类为止,还并没有体现出SpringMVC以DispatcherServlet为中心的特点。到现在为止,AbstractContextLoadInitializer抽象类表明为了搭建SpringMVC,需要向ServletContext注册一个监听器,以及需要一个Spring容器。
AbstractDispatcherServletInitializer抽象类进一步继承AbstractContextLoadInitializer。并且在这个抽象类中完成了将DispatcherServlet注册到ServletContext。并且在这个抽象类中定义了为DispatcherServlet添加过滤器、设置响应路径等方法。更值得注意的是又声明了一个抽象方法:
这个抽象方法表明DispatcherServlet自己还会持有一个Spring IoC容器。而ServletContext也会持有一个Spring IoC容器。
AbstractAnnotationConfigDispatcherServletInitializer抽象类进一步的继承AbstractDispatcherServletInitialize,并且表明要以注解配置的形式完善DispatcherServlet的相关设置。
可以看到AbstractAnnotationConfigDispatcherServletInitializer要求它的实现类提供Java配置类,来完成对两个Spring容器的配置。
因为,如果要快速的搭建SpringMVC,只需要一个类来继承AbstractAnnotationConfigDispatcherServletInitializer,Servlet容器会穿过层层类找到这个实现类,并且已经把你设置好了DispatcherServlet。实现类需要提供的只有两个Java配置类,和设置DispatcherServlet的过滤路径。