Spring MVC 是Spring的Web框架和Spring具有完美的契合,Spring MVC基于模型-视图-控制器(Model-View-Controller)模式实现。
一:Spring MVC的处理请求的流程
1:用户通过浏览器发送请求(1),Spring MVC所有的请求都会先到达前端控制器DispatcherServlet,它本身不做任何事,相当于起到了一个中央调配的作用。(前端控制器是常用的web应用程序模式)
2:DispatcherServlet根据HandlerMapping处理器映射器来找到具体的处理器(2,3),处理器映射会根据URL所携带的信息进行决策。
3:处理器完成逻辑处理之后将请求连同模型和视图名发送给DispatcherServlet(4,5,6,7),这样可以做到处理器和特定视图解耦的作用。
4:DispatcherServlet使用视图解析器(ViewResolver)将逻辑视图名匹配为一个特定的视图实现(不仅仅局限于JSP)(8,9)。
5:DispatcherServlet最后是视图的实现,在这里它交付模型数据,请求任务也差不多完成了,视图使用模型数据渲染输出,响应给客户端(8,9,10,11)。
二:使用注解的方式搭建Spring MVC
1:配置DispatcherServlet
package spittr.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class SpittrWepAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
//getRootConfigClasses(),返回的带有@Configuration注解的类将会用来配置ContextLoaderListener创建的应用上下文中的bean。
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{RootConfig.class};
}
//getServletConfigClasses(),返回的是带有@Configuration注解的类将会用来定义DispatcherServlet应用上下文的bean。
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
//它会将一个或多个路径映射到DispatcherServlet上
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
AbstractAnnotationConfigDispatcherServletInitializer实现了WebApplicationInitializer接口会自动配置DispatcherServlet和Spring应用上下文。
2:对AbstractAnnotationConfigDispatcherServletInitializer进行解析
Spring 3.0环境,容器会在类路径中查找实现了javax.servlet.ServletContainerInitializer接口的类,如果发现就用它来配置 Servlet容器。Spring提供了它的实现类SpringServletContainerInitializer,这个类查找实现WebApplicationInitializer接口的类并将配置任务交给它们完成,Spring 3.2 提供了一个便利的WebApplicationInitializer实现类 AbstractAnnotationConfigDispatcherServletInitializer,因此容器会自动发现它,并用它来配置Servlet上下文。
上图实现的三个方法:
(1):getServletMappings(),它会将一个或多个路径映射到DispatcherServlet上。
(2):getRootConfigClasses(),返回的带有@Configuration注解的类将会用来配置ContextLoaderListener创建的应用上下文中的bean。
(3):getServletConfigClasses(),返回的是带有@Configuration注解的类将会用来定义DispatcherServlet应用上下文的bean。
3:ContextLoaderListener和DispatcherServlet详解
DispatcherServlet启动时会创建Spring应用上下文,并加载配置文件或配置类中所声明的bean。实际上我们希望DispatcherServlet加载包含web组件的bean,如控制器,视图解析器以及处理器映射器等,而ContextLoaderListener加载应用中的其它bean,通常是驱动应用后端的中间件和数据层组件。
4:配置WebConfig
package spittr.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan("spittr.config")
public class WebConfig extends WebMvcConfigurerAdapter {
//配置静态资源的处理,configurer.enable()要求DispatcherServlet对静态资源的请求转发到Servlet容器默认的Servlet上,而不是使用DispatcherServlet本身处理
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
//配置JSP视图解析器,Spring自带了13个视图解析器
@Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver resourceViewResolver = new InternalResourceViewResolver();
resourceViewResolver.setPrefix("/WEB-INF/views/");
resourceViewResolver.setSuffix(".jsp");
resourceViewResolver.setExposeContextBeansAsAttributes(true);
return resourceViewResolver;
}
}
5:配置RootConfig
package spittr.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@ComponentScan(basePackages = {"spittr"},
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,value = EnableWebMvc.class)
})
public class RootConfig {
}
至此一个简单的Spring MVC已配置完成,下面要做的是配置Controller,及其后的业务逻辑。