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

最新文章

  1. jquery----中级函数
  2. mac os中配置多个jdk(转载+)
  3. [javaSE] 反射-Class类的使用
  4. HTML5+学习笔记1-------边看代码边研究中
  5. 后缀数组(模板题) - 求最长公共子串 - poj 2774 Long Long Message
  6. codeforces 687D Dividing Kingdom II 带权并查集(dsu)
  7. [Java] 实例创建的步骤
  8. CSS常用选择器
  9. Qt的十六进制的控件
  10. java 解析国密SM2算法证书
  11. javaScript设计模式之常用工厂模式
  12. kindeditor编辑器,图片上传功能齐全
  13. w3c学习总结1
  14. Optimize For Ad Hoc Workloads
  15. java工具类(一)之服务端java实现根据地址从百度API获取经纬度
  16. 类System
  17. C语言中return 0和return 1和return -1
  18. Java 创建线程/停止线程
  19. 手把手教您定制化Centos6.x安装界面
  20. MySQL报1130错误解决办法

热门文章

  1. c# T4模板生成实体类(sqlserver)
  2. 【一起学源码-微服务】Nexflix Eureka 源码四:EurekaServer启动之完成上下文构建及EurekaServer总结
  3. 机器学习之路--Numpy
  4. 小白学 Python 爬虫(35):爬虫框架 Scrapy 入门基础(三) Selector 选择器
  5. 一个.NET程序员 &quot;2019&quot; 跳槽3次的悲惨故事
  6. 【tf.keras】AdamW: Adam with Weight decay
  7. sqlserver 存储过程调Api接口
  8. 用VSCode插件来一键填满Github的绿色格子吧-AutoCommit
  9. 快速搭建一个自己的个人博客(Github Pages~二次元主题)
  10. 【设计模式】 (2)关于UML