Published on

配置 Spring MVC 开发环境

Authors
  • avatar
    Name
    Hentai
    Twitter

Demo

Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从一开始就包含在 Spring Framework 中。 正式名称“Spring Web MVC”来自其源模块的名称(spring-webmvc),但更常见的是“Spring MVC”。

DispatcherServlet

Spring MVC 与许多其他 Web 框架一样,围绕前端控制器模式设计,其中中央 Servlet DispatcherServlet 为请求处理提供共享算法,而实际工作由可配置的委托组件执行。 该模型非常灵活,支持多种工作流程。

DispatcherServlet 与任何 Servlet 一样,需要根据 Servlet 规范通过使用 Java 配置或在 web.xml 中进行声明和映射。 反过来,DispatcherServlet 使用 Spring 配置来发现请求映射、视图解析、异常处理等所需的委托组件。

以下 web.xml 配置示例注册并初始化 DispatcherServlet:

<web-app>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/app-context.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>app</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>

</web-app>

MVC 配置

在 XML 配置中,可以使用 <mvc:annotation-driven> 元素来启用 MVC 配置,如以下示例所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <mvc:annotation-driven/>

</beans>

Message Converters

由于 Spring 的 HTTP 默认消息转换器支持,无需手动进行此转换。 只需将 Jackson 2 添加在类路径上,会自动选择 Spring 的 MappingJackson2HttpMessageConverter 将实例转换为 JSON。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.3</version>
</dependency>

配置 Thymeleaf

Thymeleaf 提供了一组 Spring 集成,允许您将其用作 Spring MVC 应用程序中 JSP 的全功能替代品。为了实现更容易和更好的集成,Thymeleaf 提供了一种语法,它专门实现了所有需要的特性,以便它与 Spring 正确工作。这种特定语法基于 Thymeleaf 标准语法,并在名为 org.thymeleaf.spring4.dialect.Spring-StandardDialect 的类中实现,该类实际上是从 org.thymeleaf.standard.StandardDialect 扩展而来的。

创建一个新模板引擎类的实例,该类自动执行所有必需的配置步骤:org.thymeleaf.spring4.SpringTemplateEngine

bean 配置:

<bean id="templateResolver"
       class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
  <property name="prefix" value="/WEB-INF/templates/" />
  <!-- 默认值 -->
  <property name="suffix" value=".html" />
  <property name="templateMode" value="HTML" />
  <!-- 模板在修改时自动更新. -->
  <property name="cacheable" value="true" />
</bean>
    
<bean id="templateEngine"
      class="org.thymeleaf.spring5.SpringTemplateEngine">
  <property name="templateResolver" ref="templateResolver" />
  <!-- 使用 Spring 4.2.4 或更高版本启用 SpringEL 编译器可以加快速度 -->
  <!-- 是的,因此默认情况下此标志为“false”以实现更安全的向后兼容性。 -->
  <property name="enableSpringELCompiler" value="true" />
</bean>

Spring MVC 中的视图和视图解析器

Spring MVC 中有两个接口符合其模板系统的核心:

  • org.springframework.web.servlet.View
  • org.springframework.web.servlet.ViewResolver

在应用程序中查看模型页面,并允许通过将它们定义为 bean 来修改和预定义它们的行为。 视图负责渲染实际的 HTML 界面,通常通过执行某些模板引擎,如 Thymeleaf。

ViewResolver 是负责为特定操作和语言环境获取 View 对象的对象。 通常,Controller 要求 ViewResolver 转发到具有特定名称的视图(Controller 方法返回的字符串),然后应用程序中的所有视图解析器按有序链执行,直到其中一个能够解析该视图,其中 如果返回 View 对象并将控制权传递给它以呈现 HTML。

如果向 ViewResolver 询问一个没有对应 bean 的视图(这是常见的情况),则会临时创建一个新的 View 对象并返回。

过去 Spring MVC 应用程序中 JSP+JSTL ViewResolver 的典型配置如下所示:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
  <property name="prefix" value="/WEB-INF/jsps/" />
  <property name="suffix" value=".jsp" />
  <property name="order" value="2" />
  <property name="viewNames" value="*jsp" />
</bean>

快速查看它的属性就足以了解它是如何配置的:

  • viewClass 建立 View 实例的类。 这是 JSP 解析器所需要的,但当使用 Thymeleaf 时根本不需要它。
  • prefixsuffix 与 Thymeleaf 的 TemplateResolver 对象中相同名称的属性类似的方式工作。
  • order 建立在链中查询 ViewResolver 的顺序。
  • viewNames 允许定义(使用通配符)将由此 ViewResolver 解析的视图名称。

Thymeleaf 中的视图和视图解析器

Thymeleaf 提供了上述两个接口的实现:

  • org.thymeleaf.spring4.view.ThymeleafView
  • org.thymeleaf.spring4.view.ThymeleafViewResolver

由于 Controller 的执行,这两个类将负责处理 Thymeleaf 模板。

Thymeleaf View Resolver 的配置与 JSP 的配置非常相似:

<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
  <property name="templateEngine" ref="templateEngine" />
  <property name="order" value="1" />
  <!-- <property name="viewNames" value="*.html,*.xhtml" /> -->
  <property name="characterEncoding" value="UTF-8" />
</bean>

templateEngine 参数就是定义的 SpringTemplateEngine 对象。 其他两个(orderviewNames)都是可选的,与之前看到的 JSP ViewResolver 中的含义相同。

请注意,不需要指定 prefixsuffix 参数,因为它们已经在模板解析器中指定(它又被传递给模板引擎)。

配置 MyBatis-Spring

MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapperSqlSession 并注入到 bean 中,以及将 Mybatis 的异常转换为 Spring 的 DataAccessException。 最终,可以做到应用代码不依赖于 MyBatis,Spring 或 MyBatis-Spring。

要和 Spring 一起使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:一个 SqlSessionFactory 和至少一个数据映射器类。

在 MyBatis-Spring 中,可使用 SqlSessionFactoryBean 来创建 SqlSessionFactory。 要配置这个工厂 bean,只需要把下面代码放在 Spring 的 XML 配置文件中:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath*:mappers/**/*.xml" />
</bean>

SqlSessionFactory 有一个唯一的必要属性:用于 JDBC 的 DataSource。这可以是任意的 DataSource 对象,它的配置方法和其它 Spring 数据库连接是一样的。

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <context:property-placeholder location="classpath:jdbc.properties"/>

一个常用的属性是 configLocation,它用来指定 MyBatis 的 XML 配置文件路径。它在需要修改 MyBatis 的基础配置非常有用。通常,基础配置指的是 <settings><typeAliases> 元素。

需要注意的是,这个配置文件并不需要是一个完整的 MyBatis 配置。确切地说,任何环境配置(<environments>),数据源(<DataSource>)和 MyBatis 的事务管理器(<transactionManager>)都会被忽略。 SqlSessionFactoryBean 会创建它自有的 MyBatis 环境配置(Environment),并按要求设置自定义环境的值。

如果 MyBatis 在映射器类对应的路径下找不到与之相对应的映射器 XML 文件,那么也需要配置文件。这时有两种解决办法:第一种是手动在 MyBatis 的 XML 配置文件中的 <mappers> 部分中指定 XML 文件的类路径;第二种是设置工厂 bean 的 mapperLocations 属性。

mapperLocations 属性接受多个资源位置。这个属性可以用来指定 MyBatis 的映射器 XML 配置文件的位置。属性的值是一个 Ant 风格的字符串,可以指定加载一个目录中的所有文件,或者从一个目录开始递归搜索所有目录。

这会从类路径下加载所有在 mappers 包和它的子包中的 MyBatis 映射器 XML 配置文件。

发现映射器

不需要一个个地注册你的所有映射器。你可以让 MyBatis-Spring 对类路径进行扫描来发现它们。

有几种办法来发现映射器:

  • 使用 <mybatis:scan/> 元素
  • 使用 @MapperScan 注解
  • 在 Spring XML 配置文件中注册一个 MapperScannerConfigurer

<mybatis:scan/>@MapperScan 都在 MyBatis-Spring 1.2.0 中被引入。@MapperScan 需要你使用 Spring 3.1+。

从 2.0.2 开始,映射器扫描功能支持一个选项(lazy-initialization),用于控制映射器 bean 的延迟初始化启用/禁用。 添加此选项是支持 Spring Boot 2.2 支持的延迟初始化控制功能。 此选项的默认值为 false(= 不使用延迟初始化)。 如果想对mapper bean使用延迟初始化,应该明确设置为 true

MapperScannerConfigurer

MapperScannerConfigurer 是一个 BeanDefinitionRegistryPostProcessor,这样就可以作为一个 bean,包含在经典的 XML 应用上下文中。为了配置 MapperScannerConfigurer,使用下面的 Spring 配置:

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  <property name="basePackage" value="com.example.mapper" />
</bean>

配置 SLF4J

Java 的简单日志外观 (SLF4J) 用作各种日志框架(例如 java.util.logginglogbacklog4j)的简单外观或抽象,允许最终用户在部署时插入所需的日志框架。

启用 SLF4J 的库意味着仅添加一个强制依赖项,即 slf4j-api.jar。 如果在类路径上没有找到绑定/提供者,那么 SLF4J 将默认为无操作实现。

从 1.7.35 版开始,通过 Maven <relocation> 指令声明对重定向的依赖。 org.slf4j:slf4j-log4j12org.slf4j:slf4j-reload4j

<dependency> 
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.7.36</version>
</dependency>

带有属性的配置

从 2.4 版开始,Log4j 现在支持通过属性文件进行配置。 注意,属性语法与 Log4j 1 中使用的语法不同。与 XML 和 JSON 配置一样,属性配置根据插件和插件属性定义配置。log4j.properties

# Root logger option
log4j.rootLogger=DEBUG, file, stdout
#log4j.logger.org.thymeleaf=INFO

# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=D:/Code/.logs/springmvc-test.log
log4j.appender.file.MaxFileSize=1024MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.Encoding=UTF-8
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

参考链接