纯 JAVA 搭建 Spring MVC 项目

1. 前言

Spring MVC 项目可以真正意义上实现零 XML 配置,注意不是不配置,而是可以不使用 XML 配置。Spring MVC 提供了大量的注解,让 JAVA 开发者以自己最擅长的 JAVA 语法编写配置信息。

本节课程,将向大家介绍如何使用纯 JAVA 的方式搭建 Spring MVC 项目,通过本节课程,你将学习到:

  • 了解搭建 Spring MVC 的流程。这既是本章节的难点也是重点;
  • 了解纯 JAVA 配置的重要注解。

2. 前期准备

欲善其功,必先利其器。使用 Spring MVC 之前,准备好一系列的工具软件。

  • 操作系统: 可以选择 WIndowsLiunxMAC 。本课程选择 WIndows 操作系统;
  • IDE 工具: 本课程选择 eclipse。这不是唯一、强制的要求,你可以选择自己喜欢的开发工具;
  • JAVA JDK : 这个不用多说,它是必须的。本文选择 JDK 1.8+
  • 服务器组件: 本文选择 tomcat 8.X

基于 Spring MVC 的开发本质还是编写 JAVA 程序,区别在于 Spring MVC 提供了更高级层面的 API 组件。所以,开发时需要在项目中添加 Spring MVC 相关的 API 包。有 2 种方案可获取这些 JAR 依赖包:

Tips: 本课程采用 Spring Framework 5.1.13 版本。

  • 使用 Maven 依赖管理功能自动添加 Spirng MVC 项目所需要的依赖包。本课程使用此方案。

3. 搭建流程

3.1 新建 maven 项目

  1. eclipse 中新建 Maven 项目;

图片描述

  1. 选择 maven 中的 webapp 骨架模板 ,在后续的对话框中输入项目名称等信息。

图片描述

3.2 添加依赖包

项目创建成功后,会发现项目上有红色的错误提示,这个不用紧张。因为项目自动创建了一个 jsp 文件,而 jsp 所依赖的 servlet 包我们还没有加进来。

打开项目中的 pom.xml 文件,在文件中添加项目所需要的依赖 jar 包:

  • javax.servlet-api: servlet 规范包;
  • spring-context: spring 最基础、最重要的核心包。Maven 有一个依赖传递功能,会自动添加 spring-context 所依赖的其它包;
  • spring-web: springweb 项目的支持包,这个不用解释,肯定不能少;
  • spring-webmvc: 从名字上看,知道它应该是主角,Spring MVC 核心包。

完整的依赖信息如下:

<dependencies>
	<dependency>
		<groupId>junit</groupId>
		<artifactId>junit</artifactId>
		<version>4.5</version>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>5.1.13.RELEASE</version>
		<scope>compile</scope>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
		<version>5.1.13.RELEASE</version>
		<scope>compile</scope>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
		<version>5.1.13.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>javax.servlet-api</artifactId>
		<version>4.0.1</version>
		<scope>provided</scope>
	</dependency>
</dependencies>

Maven 会自动从远程仓库下载这些依赖包,项目中也可以看到下载下来的依赖包:

图片描述

大家会看到,除了在 pom.xml 文件中指定的依赖包外,还有其它的包,这个就是 Maven 的依赖传递功能实现的。好了! 有了这些包后,就可以使用 Spring 提供的 WEB MVC API 了。

3.3 两个上下文对象

Spring 提供了很厉害的 IOC & DI 工厂,这个工厂对象在 web 项目中的具体名称叫 WebApplicationContext,也称其为上下文对象,用来创建 Spring MVC 项目中的各色功能组件。所以,欲使用 Spring MVC,则先要想办法创建上下文对象。

Spring 建议 Spring MVC 项目中提供 2WebApplicationContext 对象:

  • 一个 WebApplicationContext 对象用来创建 Spring MVC 相关的组件,称其为 Web 上下文对象
  • 一个用来创建程序中其它的具体功能组件(如逻辑组件、数据层访问组件……),称其为 Root (根)上下文对象

图片描述

两个上下文对象各自负责的组件范围

如果只创建一个 WebApplicationContext 对象会产生什么结果?

如果仅仅是测试、学习,从初期来看,没有什么不可。从长远来看,建议还是听从建议。

Tips: 这两个 WebApplicationContext对象存在底层上的差异性。一个支持事务,另一个不支持。有各自的职责。

Spring MVC 提供了一个叫 DispatcherServlet 的组件(本质就是一个 Servlet),此组件用来作为进入程序的唯一入口。是 Spring MVC 项目的“门神”。

Tips: 可称 DispatcherServlet 为中央控制器或前端控制器。

好了!现在理一下头绪:

  • 一定要在整个项目运作之前先让 DispatcherServlet 组件开始工作,DispatcherServlet 除了充当门神外,还会创建一个与自己有关联的 WebApplicationContext 工厂对象,即 Web 上下文对象
  • Spring 另提供有名为 ContextLoaderListener 的监听器组件,它可以监听程序的启动过程,并在程序启动时创建另一个 WebApplicationContext 工厂对象,即 Root 上下文对象

3.4 编写配置类

下面,使用纯 JAVA 方式为 Spring MVC 的初次运行提供必备的配置信息 。

先认识一个组件,做好思想准备,这个组件名字很长,别吓到你了:AbstractAnnotationConfigDispatcherServletInitializer。名字虽然有点长,但是很体贴,怕你不知道它的作用,名字本身就告诉了你:基于注解的初始化 DispatcherServlet 的抽象组件,简单说就是一个 WEB 初始化组件,用来替代 web.xml 的功能。

该动手了!构建一个继承了AbstractAnnotationConfigDispatcherServletInitializer 的类:

package com.mk.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
	@Override
	protected Class<?>[] getRootConfigClasses() {	
		return null;
	}
	@Override
	protected Class<?>[] getServletConfigClasses() {
		return null;
	}
	@Override
	protected String[] getServletMappings() {
		return null;
	}
}

嘿!居然有 3 个方法强制性要求实现,那么,这 3 个方法分别是干嘛用的?

WebInitializer 这个类会自动创建 Spring MVCDispatcherServlet 核心组件,并且创建 2 个 WebApplication 上下文对象。

Spring 不能白学,是吧,工厂再厉害,你也得告诉它你要创建什么吧。大家还记得这些信息你原来是放在哪里的吗?

想起来了吧,你是放在 XML 文件中的,本文则是放在 JAVA 类中。所以这 3 个方法中有 2 个方法是用来指定这 2 个上下文对象分别对应的配置类是谁。

知道原因了,立马准备好 2 个配置类。

//web 上下文对象的配置类
@Configuration
@ComponentScan(basePackages = { "com.mk.web" }, excludeFilters = {
		@Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class) })
public class RootConfig {
}
// Root 上下文对象的配置类
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.mk.web.action" })
public class WebConfig {

}

这里有 3 个注解需要说明 一下:

  • @Configuration 注解:说明这个类是配置类;

Tips: 配置类用来替代 XML 配置文件。

  • @EnableWebMvc 注解: 很好理解,启动 Spring MVC 相关功能;

  • @ComponentScan 注解: 指定上下文对象各自负责的组件所在包。

Tips: Root 配置类中需要排除 Web 配置类负责的区域。

在重新完善 WebInitializer 类之前,说明一下,另一个方法是用来指定前端控制器可以响应的请求地址。OK!让我们再来看看这 3 个方法本来应该的样子:

@Override
protected Class<?>[] getRootConfigClasses() {	
	return new Class[] { RootConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class};
}
//接受所有请求
@Override
protected String[] getServletMappings() {
	return new String[] {"/"};
}

3.3 项目测试

经过这一番折腾后,Spring MVC 项目的基础架构就完成了,把项目部署到服务器(tomcat)中。查看 tomcat 启动时的输出日志中是否存在下面的信息。如果存在,表示 Spring MVC 项目初始化成功。

图片描述

在浏览器的地址栏中输入:http://localhost:8888/sm-demo/

Tips: 我的端口号是 8888。

如果浏览器中输出 Hello World ,恭喜,咱们取得了使用 Spring MVC 第一阶段的成功。

4.视频演示

5. 小结

本节课程和大家一起聊了聊如何使用纯 JAVA 的方式搭建 Spring MVC 项目 。

通过本章节的学习,大家一定要记住 DispatcherServlet 这个核心组件,并要理解 Spring MVC 项目中为什么需要 2 个 WebApplicationContext 一起工作的。并深深地记住 JAVA 配置相关的几个注解。