XML 搭建
<web-app>
<display-name>Archetype Created Web Application</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring.xml</param-value>
</context-param>
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/web.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
注解配置
使用接口 WebApplicationInitializer 来实例化 Spring 容器 和 DispathServlet
public class MyWebApplicationInitializer implements WebApplicationInitializer {
// public class MyWebApplicationInitializer implements TestWebApplicationInitializer {
/**
* Spring MVC 0-XML 配置的原理:
*
* 因为 servlet 3.0 的一个新规范(ServletContainerInitializer),
* 而 tomcat 也遵守了了这个规范,所以会调用 实现了 WebApplicationInitializer 的 onStartup 方法
*
* Spring 定义了一个 org.springframework.web.SpringServletContainerInitializer 类,实现了 servlet 3.0 的这个新规范
*
* Spring 实现方式
* spring-web\META-INF\services\javax.servlet.ServletContainerInitializer,是指需要实现的接口
* javax.servlet.ServletContainerInitializer 文件里面的 org.springframework.web.SpringServletContainerInitializer 是实现类
* @HandlesTypes(WebApplicationInitializer.class) 会由容器进行解析里面定义的接口,找出所有实现类,并回调给 Set<Class<?>> webAppInitializerClasses
* Spring 再对 webAppInitializerClasses 的子类进行遍历,分别调用其 onStartup 的方法
*
* @param servletContext Web上下文对象
* @throws ServletException
*/
public void onStartup(ServletContext servletContext) throws ServletException {
System.out.println("-------onStartup-------");
// Load Spring web application configuration
AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
ac.register(AppConfig.class);
// ac.refresh();
// Create and register the DispatcherServlet
// DispatcherServlet 的 init 方法
DispatcherServlet servlet = new DispatcherServlet(ac);
ServletRegistration.Dynamic registration = servletContext.addServlet("app", servlet);
registration.setLoadOnStartup(1);
registration.addMapping("*.do");
// registration.addMapping("/*");
}
}
使用 WebMvcConfigurer 来配置 Spring MVC 环境
@Configuration
@ComponentScan("org.wesoft.mvc")
@EnableWebMvc // 相当于 XML 中的 <mvc:annotation-driven/>
public class AppConfig implements WebMvcConfigurer {
// public class AppConfig extends WebMvcConfigurationSupport {
/*
Apache Commons FileUpload
To use Apache Commons FileUpload,
you can configure a bean of type CommonsMultipartResolver with a name of multipartResolver.
You also need to have commons-fileupload as a dependency on your classpath.
*/
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
return commonsMultipartResolver;
}
// 会在 Spring mvc 环境初始化完成之后,加载这个方法
@Autowired
public void iniArgumentsResolvers(RequestMappingHandlerAdapter requestMappingHandlerAdapter) {
List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<>(requestMappingHandlerAdapter.getArgumentResolvers());
// 获取自定义的参数解析器
List<HandlerMethodArgumentResolver> customArgumentResolvers = requestMappingHandlerAdapter.getCustomArgumentResolvers();
// 删除原来集合中的自定义参数解析器
argumentResolvers.removeAll(customArgumentResolvers);
// 重新加入到最前面
argumentResolvers.addAll(0, customArgumentResolvers);
// 重新设置参数解析器
requestMappingHandlerAdapter.setArgumentResolvers(argumentResolvers);
}
/**
* 视图处理
*
* @param registry
*/
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/page/", ".html");
}
/**
* 添加消息解析器
*
* @param converters
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter jsonHttpMessageConverter = new FastJsonHttpMessageConverter();
converters.add(jsonHttpMessageConverter);
}
/**
* 添加参数解析器
*
* @param resolvers initially an empty list
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
// 这里其实是传过来一个空集合,对应着 customArgumentResolvers
// 也就是我们其实是在 customArgumentResolvers 里添加自定义方法
// 然后 spring mvc 会将这个集合合并到 argumentResolvers 中,所以并不能保证执行顺序
resolvers.add(new LoginUserResolver());
}
}