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()); }}