根据 Servlet 3.0 的新特性,web 容器启动的时候会扫描每个 jar 包下的 /META-INF/services/javax.servlet.ServletContainerInitializer
文件。
使用 Spring MVC 的 web 包,可以看到有这个文件:
文件内容如下:
org.springframework.web.SpringServletContainerInitializer
该类的头部信息如下:
@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
Spring 的应用一启动就会加载感兴趣的 WebApplicationInitializer
接口下的组件,并且为这些组件创建对象。
AbstractContextLoaderInitializer
:创建根容器 rootAppContext;AbstractDispatcherServletInitializer
:- 创建一个 web 的 IOC 容器
servletAppContext
; - 创建一个
dispatcherServlet
; - 将创建的
dispatcherServlet
添加到容器中;
- 创建一个 web 的 IOC 容器
AbstractAnnotationConfigDispatcherServletInitializer
:注解方式配置dispatcherServlet
的初始化器:- 首先创建根容器;
- 创建 web
IOC
容器;
所以我们要想以注解的方式启动 SpringMVC 只需要写一个类继承 AbstractAnnotationConfigDispatcherServletInitializer
,然后实现抽象方法指定 DispatcherServlet
的配置信息。
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
/**
* 获取根容器的配置类: 相当于 Spring 的配置文件
*
* @return 根容器的配置类
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{RootConfig.class};
}
/**
* 获取 Web 容器的配置类: 相当于 Spring MVC 的配置文件
*
* @return Web 容器的配置类
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{ServletConfig.class};
}
/**
* 获取 Servlet 的映射信息
* "/" 代表拦截所有请求: 包括静态资源,但是不拦截 *.jsp
* "/*" 也是拦截所有请求,也拦截 *.jsp
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
指定两个类,一个是根容器的配置类,另一个是 Web 容器的配置类,两个容器是父子容器的关系。
根容器只扫描所有的 Service
和 Repository
组件,所以要排除 Controller
。
@ComponentScan(value = "top.wsuo", excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})
})
public class RootConfig {
}
而 Web 容器只扫描 Controller
。
@ComponentScan(value = "top.wsuo", includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})
}, useDefaultFilters = false)
@EnableWebMvc
public class ServletConfig {
}
我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2g2deaym94lc8