Spring注解开发系列VIII --- SpringMVC
SpringMVC是三层架构中的控制层部分,有过JavaWEB开发经验的同学一定很熟悉它的使用了。这边有我之前整理的SpringMVC相关的链接:
看过之后大致对springmvc有一个了解,但对于真正完全掌握springmvc还差得远,本篇博客主要针对的是springmvc的注解开发,传统的项目使用spingmvc避免不了地需要在web.xml里配置前端控制器等等,想要在项目中优雅地去掉这些配置,还得学习如何使用万能的注解来代替这些配置。
Servlet3.0整合SpringMVC
一.原理分析
1) 首先需要导入pom依赖gav:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.11.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
2) web容器启动
1.web容器启动的时候会扫描每个jar包下的META-INF/services/javax.servlet.ServletContainerInitializer文件

2.加载这个文件指定类的org.springframework.web.SpringServletContainerInitializer

3.Spring的应用一启动会加载感兴趣的WebApplicationInitializer接口下的所有组件
4.并且为WebApplicationInitializer组件创建对象(非接口、非抽象类)
@HandlesTypes({WebApplicationInitializer.class})
public class SpringServletContainerInitializer implements ServletContainerInitializer {
public SpringServletContainerInitializer() {
}
public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {
List<WebApplicationInitializer> initializers = new LinkedList();
Iterator var4;
if (webAppInitializerClasses != null) {
var4 = webAppInitializerClasses.iterator();
while(var4.hasNext()) {
Class<?> waiClass = (Class)var4.next();
if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
try {
initializers.add((WebApplicationInitializer)waiClass.newInstance());
} catch (Throwable var7) {
throw new ServletException("Failed to instantiate WebApplicationInitializer class", var7);
}
}
}
}
if (initializers.isEmpty()) {
servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
} else {
servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
AnnotationAwareOrderComparator.sort(initializers);
var4 = initializers.iterator();
while(var4.hasNext()) {
WebApplicationInitializer initializer = (WebApplicationInitializer)var4.next();
initializer.onStartup(servletContext);
}
}
}
}
5.WebApplicationInitializer的子类
AbstractContextLoaderInitializer:创建根容器,createRootApplicationContext();
AbstractDispatcherServletInitializer:
创建一个web的ioc容器,createServletApplicationContext();
创建了DispacherServlet:createDispacherServlet();
将创建的DispacherServlet添加到ServletContext中
AbstractAnnotationConfigDispatcherServletInitializer:注解方式配置的DispacherServlet初始化器
创建根容器createRootApplicationContext()
创建一个webioc容器createServletApplicationContext()
总结:要以注解方式来启动SpringMVC,实现配置类的方式,需要继承AbstractAnnotationConfigDispatcherServletInitializer,实现抽象方法指定的DispacherServlet的配置信息。
二.整合SpringMVC
经过上述分析,我们来试着整合SpringMVC。
1.创建一个类来继承AbstractAnnotationConfigDispatcherServletInitializer
//在web容器启动的时候创建对象,调用方法来初始化容器以及前端控制器
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
/**
* 获取根容器的配置(类似于之前监听器配置spring的配置文件)
* <listener>
* <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
* </listener>
*
*<context-param>
* <param-name>contextConfigLocation</param-name>
* <param-value>classpath:spring/applicationContext-*.xml</param-value> 。
* </context-param>
*
*
*
**/ @Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{RootConig.class};
} /**
* 获取web容器的配置类(类似于springmvc的配置文件)(前端控制器)子容器
* @return
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{AppConfig.class};
} /**
* 获取DispatcherServlet的映射信息
*
* {"/"}:拦截所有请求包括静态资源(xx.js,xx.png),不包括*.jsp
* {"/*"}:拦截所有请求,包括*.jsp,jsp页面是tomcat的jsp引擎解析的
* @return
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
2.创建根容器的配置
//Spring的容器不扫描Controller,交给SpringMvc扫描
@ComponentScan(value = "com.wang",excludeFilters =
{@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})})
public class RootConig {
}
3.创建web容器的配置类
//SpringMVC只扫描Controller,子容器
//useDefaultFilters=false 禁用默认的过滤规则
@ComponentScan(value = "com.wang",includeFilters =
{@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})},useDefaultFilters = false)
public class AppConfig {
}
4.将配置类加入到AbstractAnnotationConfigDispatcherServletInitializer的子类中


5.创建Controller,Service类测试
@Controller
public class HelloController {
@Autowired
private MyHelloService myHelloService;
@ResponseBody
@RequestMapping("/myhello")
public String hello(){
return myHelloService.sayHello();
}
}
@Service
public class MyHelloService {
public String sayHello(){
return "hello";
}
}
启动应用,访问"/myhello"请求,若能正常访问到该请求,说明上述配置类生效。
三.定制SpringMVC
1). @EnableWebMVC:开启SpringMVC定制配置功能相当于<mvc:annotation-driven/>

2). 配置组件(视图解析器、视图映射、静态资源映射、拦截器)
@ComponentScan(value = "com.wang",includeFilters =
{@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})},useDefaultFilters = false)
@EnableWebMvc
public class AppConfig extends WebMvcConfigurerAdapter {
/**
* 路径映射规则
* @param pathMatchConfigurer
*/
@Override
public void configurePathMatch(PathMatchConfigurer pathMatchConfigurer) { } /**
* 视图解析器
* @param registry
*/
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
//默认所有的页面都从"/WEB-INF/*.jsp"
//registry.jsp();
registry.jsp("/WEB-INF/views/",".jsp");
} /**
* 配置静态资源访问,将springmvc处理不了的请求交给springmvc,开启后可以访问静态资源(*.js,*.jpg,...)
* @param defaultServletHandlerConfigurer
*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer defaultServletHandlerConfigurer) {
defaultServletHandlerConfigurer.enable();//相当于开启了default-servlet-handler <mvc:default-servlet-handler/>
} /**
* 添加拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/success");
}
}
Spring注解开发系列VIII --- SpringMVC的更多相关文章
- Spring注解开发系列Ⅵ --- AOP&事务
注解开发 --- AOP AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,横向重复,纵向抽取.详细的AO ...
- Spring注解开发系列专栏
这个系列主要是讲Spring注解的使用,可以为后面SpringBoot的学习带来一定的帮助.我觉得从Spring直接过度到SpringBoot还是有点快,还是得需要一个演变的过程.从Spring开发, ...
- Spring注解开发系列Ⅰ--- 组件注册(上)
传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点:1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml文件 ...
- Spring注解开发系列Ⅴ --- 自动装配&Profile
自动装配: spring利用依赖注入和DI完成对IOC容器中各个组件的依赖关系赋值.自动装配的优点有: 自动装配可以大大地减少属性和构造器参数的指派. 自动装配也可以在解析对象时更新配置. 自动装配的 ...
- Spring注解开发系列VII --- Servlet3.0
Servlet3.0简介 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若干新特性用 ...
- Spring注解开发系列Ⅱ --- 组件注册(下)
1.@Import注册组件 @Import主要功能是通过导入的方式实现把实例加入springIOC容器中, /** * 给容器注册组件 * 1.包扫描+组件标注注解(@Controller,@Serv ...
- Spring注解开发系列Ⅲ --- 生命周期
Bean的生命周期 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解. 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: S ...
- Spring注解开发系列Ⅳ --- 属性赋值
在Spring框架中,属性的注入我们有多种方式,我们可以通过构造方法注入,可以通过set方法注入,也可以通过p名称空间注入,方式多种多样,对于复杂的数据类型比如对象.数组.List集合.map集合.P ...
- Spring注解开发系列Ⅸ --- 异步请求
一. Servlet中的异步请求 在Servlet 3.0之前,Servlet采用Thread-Per-Request的方式处理请求,即每一次Http请求都由某一个线程从头到尾负责处理.如果要处理一些 ...
随机推荐
- django框架(1)
一什么是web框架? 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演. 对于所有的 ...
- 洛谷$P4149\ [IOI2011]\ Race$ 点分治
正解:点分治 解题报告: 传送门$QwQ$ 昂先不考虑关于那个长度的限制考虑怎么做? 就开个桶,记录所有边的取值,每次加入边的时候查下是否可行就成$QwQ$ 然后现在考虑加入这个长度的限制?就考虑把这 ...
- 洛谷$P$3327 约数个数和 $[SDOI2015]$ 莫比乌斯反演
正解:莫比乌斯反演 解题报告: 传送门! 先考虑证明一个结论,$d_{i\cdot j}=\sum_{p|i}\sum_{q|j}[gcd(p,q)==1]$ 看起来就很对的样子,但还是证下趴$QwQ ...
- selenium自动化测试之--验证码处理
由于登录反爬措施的越来越麻烦,甚至出现了12306这种看图识物的无敌验证码,我只能说,我选择死亡.这就衍生出了使用selenium来获取获取cookies. 因为经常会出现验证码,导致我们ui自动化测 ...
- MySQL基础篇(04):存储过程和视图,用法和特性详解
本文源码:GitHub·点这里 || GitEE·点这里 一.存储过程 1.概念简介 存储程序是被存储在服务器中的组合SQL语句,经编译创建并保存在数据库中,用户可通过存储过程的名字调用执行.存储过程 ...
- Spring的一些基本概念(面试备用哦)
1.什么是Spring, 它有什么特点? 包括哪些内容? Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架. ◆ 轻量——从大小与开销两方面而言Spring都是轻量的.完整 ...
- Linux之nohup命令
例:执行一个循环的脚本 可以使用sh命令就可以了 后台运行这个脚本使用& nohup能够正常在关闭xshell继续执行,而其他两种办法不行 但是注意 这&方法断掉这session后(进 ...
- .gitignore使用
一.简绍 我们做的每个Git项目中都需要一个".gitignore"文件,这个文件的作用就是告诉Git哪些文件不需要添加到版本管理中.比如我们项目中的npm包(node_modul ...
- FlashFXP中文破解 指南
flashfxp是一款使用非常广泛,功能非常更强大的FXP/FTP软件.它拥有显示彩色文字.比较CuteFTP的目录.上传和下载文件.共享文件等众多功能,其中深受用户喜爱的便是目录比较功能,它能够有效 ...
- 记录这两年是如何一步一步转型到.net core+k8s
2017年12月份,我离开北京,回到了武汉,开始在现在这家公司担任架构师工作.经过2年的时间,逐步完成以.net core+k8s为核心的技术架构.文末有彩蛋. 以下整理这两年的主要时间节点: 201 ...