SpringMVC是三层架构中的控制层部分,有过JavaWEB开发经验的同学一定很熟悉它的使用了。这边有我之前整理的SpringMVC相关的链接:

1.SpringMVC入门

2.SpringMVC进阶

3.深入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的更多相关文章

  1. Spring注解开发系列Ⅵ --- AOP&事务

    注解开发 --- AOP AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,横向重复,纵向抽取.详细的AO ...

  2. Spring注解开发系列专栏

    这个系列主要是讲Spring注解的使用,可以为后面SpringBoot的学习带来一定的帮助.我觉得从Spring直接过度到SpringBoot还是有点快,还是得需要一个演变的过程.从Spring开发, ...

  3. Spring注解开发系列Ⅰ--- 组件注册(上)

    传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点:1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml文件 ...

  4. Spring注解开发系列Ⅴ --- 自动装配&Profile

    自动装配: spring利用依赖注入和DI完成对IOC容器中各个组件的依赖关系赋值.自动装配的优点有: 自动装配可以大大地减少属性和构造器参数的指派. 自动装配也可以在解析对象时更新配置. 自动装配的 ...

  5. Spring注解开发系列VII --- Servlet3.0

    Servlet3.0简介 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若干新特性用 ...

  6. Spring注解开发系列Ⅱ --- 组件注册(下)

    1.@Import注册组件 @Import主要功能是通过导入的方式实现把实例加入springIOC容器中, /** * 给容器注册组件 * 1.包扫描+组件标注注解(@Controller,@Serv ...

  7. Spring注解开发系列Ⅲ --- 生命周期

    Bean的生命周期 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解. 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: S ...

  8. Spring注解开发系列Ⅳ --- 属性赋值

    在Spring框架中,属性的注入我们有多种方式,我们可以通过构造方法注入,可以通过set方法注入,也可以通过p名称空间注入,方式多种多样,对于复杂的数据类型比如对象.数组.List集合.map集合.P ...

  9. Spring注解开发系列Ⅸ --- 异步请求

    一. Servlet中的异步请求 在Servlet 3.0之前,Servlet采用Thread-Per-Request的方式处理请求,即每一次Http请求都由某一个线程从头到尾负责处理.如果要处理一些 ...

随机推荐

  1. nor flash之频率限制

    背景 支持一款nor flash时,出于性能考虑,一般会查看其nor支持的最高频率以及主控端spi控制器的最高频率,以选择一个合适的运行频率. 对于一款主控支持多款flash的情况,还得考虑好兼容性等 ...

  2. c# T4模板生成实体类(sqlserver)

    1.用vs新建tt文件. 2.tt文件保存就自动运行 3.tt文件代码如下,设置生成cs文件的命名空间和生成地址 <#@ template language="C#" hos ...

  3. IntelliJ IDEA使用说明

    1.IntelliJ IDEA简介: IDEA 全称 IntelliJ IDEA,是java语言开发的集成环境,IntelliJ在业界被公认为最好的java开发工具之一,尤其在智能代码助手.代码自动提 ...

  4. 天梯 L2 紧急救援 (dijkstra变形+记录路径)

    L2-001 紧急救援 (25 分) 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道 ...

  5. 【转】JavaScript 3D图表

    文章系本人原创,转载请保持完整性并注明出自<四火的唠叨> 在说3D图表以前,首先要明确两个概念,一个是数据的维度,一个是呈现数据载体的维度.对于数据的维度,一维的数据呈现,但是呈现的载体是 ...

  6. 【转】iOS 7免费设计资源汇总

    原文链接:http://mobile.51cto.com/hot-406317.htm#585532-tsina-1-28470-7e393678b940a4d55500bf3feae3d2e9 以下 ...

  7. 移动端保存当前屏幕内容为图片,canvas图片拼接

    需求:1.移动端点击分享时,截屏当前屏幕,并保存为图片  2.将截屏的图片与一张二维码图片进行拼接后,生成一张新的图片 技术栈:html2canvas.js.canvas2image.js 代码:(j ...

  8. uni app canvas 不生效

    canvas 创建canvas绘图上下文. <canvas style="width: 300px; height: 200px;" canvas-id="firs ...

  9. Java操作Jxl实现数据交互。三部曲——《第三篇》

    Java操作Jxl实现上传文本文件实现转PDF格式在线预览. 本文实现背景Web项目:前台用的框架是Easyui+Bootstrap结合使用,需要引入相应的Js.Css文件.页面:Jsp.拦截请求:S ...

  10. 图解kubernetes scheduler基于map/reduce模式实现优选阶段

    优选阶段通过分map/reduce模式来实现多个node和多种算法的并行计算,并且通过基于二级索引来设计最终的存储结果,从而达到整个计算过程中的无锁设计,同时为了保证分配的随机性,针对同等优先级的采用 ...