14SSM框架整合
对于Java EE应用程序的开发,行业中提供了非常多的技术框架,但是不管如何进行技术选型,Java EE应用都可以分为表现层、业务逻辑层和数据持久层,当前,这3个层的主流框架分别是Spring MVC、Spring和MyBatis,简称为SSM框架,Java EE应用程序也经常通过整合这3大框架来完成开发。SSM框架的整合有多种方式,本章将对目前常用的整合方式和纯注解的整合方式来对SSM框架的整合进行介绍。
14.1 常用方式整合SSM框架
14.1.1 整合思路
进行SSM框架整合时,3个框架的分工如下所示。
- MyBatis负责与数据库进行交互。
- Spring负责事务管理,Spring可以管理持久层的Mapper对象及业务层的Service对象。由于Mapper对象和Service对象都在Spring容器中,所以可以在业务逻辑层通过Service对象调用持久层的Mapper对象。
- Spring MVC负责管理表现层的Handler。Spring MVC容器是Spring容器的子容器,因此Spring MVC容器可以调用Spring容器中的Service对象。
下面通过一个图书信息查询案例来描述SSM框架的整合,案例实现思路如下。
- 搭建项目基础结构。首先需要在数据库中搭建项目对应的数据库环境;然后创建一个Maven Web项目,并引入案例所需的依赖;最后创建项目的实体类,创建三层架构对应的模块、类和接口。
- 整合Spring和MyBatis。在Spring配置文件中配置数据源信息,并且将SqlSessionFactory对象和Mapper对象都交由Spring管理。
整合Spring和Spring MVC。Spring MVC是Spring框架中的一个模块,所以Spring整合Spring MVC只需在项目启动时分别加载各自的配置即可。
14.1.2 项目基础结构搭建
接下来,根据14.1.1中的整合思路搭建SSM框架整合的项目基础结构,具体如下所示。
1.搭建数据库环境:在已有的spring数据库中创建一个名称为tb_book的表,并在tb_book表中插入数据。创建数据库和表,以及往表中插入数据的SQL语句如下所示。USE spring;
CREATE TABLE `tb_book` (
`id` INT(11) ,
`name` VARCHAR(32) ,
`press` VARCHAR(32) ,
`author` VARCHAR(32) );
INSERT INTO `tb_book` VALUES
(1, 'Java EE企业级应用开发教程', '人民邮电出版社', '黑马程序员');
2.创建一个MavenWeb项目,名称为chapter14SSM(创建过程参考第10章笔记);在pom.xml文件中引入项目依赖。
(1)Spring相关依赖。spring-context : Spring上下文;
- spring-tx : Spring事务管理;
- spring-jdbc : SpringJDBC;
- spring-test : Spring单元测试;
- spring-webmvc : Spring MVC核心。
(2)MyBatis相关依赖。mybatis : MyBatis核心;
(3)MyBatis与Spring整合包。mybatis-spring :MyBatis与Spring整合。
(4)数据源相关。druid : 阿里提供的数据库连接池。
(5)单元测试相关的依赖。junit : 单元测试,与spring-test放在一起做单元测试。
(6)ServletAPI相关的依赖。jsp-api : jsp页面使用request等对象;servlet-api : java文件使用request等对象。
(7)数据库相关的依赖。mysql-connector-java : mysql的数据库驱动包。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.edu.imust</groupId>
<artifactId>chapter14SSM</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>chapter14 Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- Spring相关依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!--Spring事务管理-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!--Spring MVC的相关依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!--MyBatis相关依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!--MyBatis与Spring整合相关依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.1</version>
</dependency>
<!--数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.20</version>
</dependency>
<!--单元测试相关的依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- 相关的依赖-->
<!--ServletAPI:引入servlet的功能-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--ServletAPI: jsp页面的功能包 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- 数据库驱动相关依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>chapter14SSM</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<port>8080</port>
<path>/chapter14SSM</path>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
3.在项目的src/main/java目录下,创建一个名为cn.edu.imust.domain的包;在该包中创建名称为Book的实体类。
package cn.edu.imust.domain;
public class Book {
private Integer id; //图书id
private String name; //图书名称
private String press; //出版社
private String author; //作者
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPress() {
return press;
}
public void setPress(String press) {
this.press = press;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
4.创建三层架构对应模块的类和接口:
(1)在项目的src/main/java目录下,创建一个名为cn.edu.imust.dao的包;在该包中创建名称为BookMapper的持久层接口,在BookMapper接口中定义findBookById()方法,通过图书id获取对应的图书信息。
package cn.edu.imust.dao;
import cn.edu.imust.domain.Book;
public interface BookMapper {
public Book findBookById(Integer id);
}
(2)在项目的src/main/resources目录下,创建路径为cn/edu/imust/dao的文件夹;在该文件夹中创建BookMapper接口对应的映射文件BookMapper.xml。
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.edu.imust.dao.BookMapper">
<select id="findBookById" parameterType="int" resultType="cn.edu.imust.domain.Book">
select * from tb_book where id = #{id}
</select>
</mapper>
(3)在项目的src/main/java目录下,创建一个名为cn.edu.imust.service的包;在该包中创建名称为BookService的业务层接口,在BookService接口中定义findBookById()方法,通过id获取对应的Book信息。
package cn.edu.imust.service;
import cn.edu.imust.domain.Book;
public interface BookService {
public Book findBookById(Integer id);
}
(4)在项目的src/main/java目录下,创建一个名为cn.edu.imust.service.impl的包;在该包中创建BookService接口的业务层实现类BookServiceImpl。BookServiceImpl类实现BookService接口的findBookById()方法。 并在类中注入一个BookMapper对象。findBookById()方法通过注入的BookMapper对象调用findBookById()方法,根据id查询对应的图书信息。
package cn.edu.imust.service.impl;
import cn.edu.imust.dao.BookMapper;
import cn.edu.imust.domain.Book;
import cn.edu.imust.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookMapper bookMapper;
@Override
public Book findBookById(Integer id) {
return bookMapper.findBookById(id);
}
}
(5)在项目的src/main/java目录下,创建一个名为cn.edu.imust.controller的包;在该包中创建名称为BookController的类。在BookController类中注入一个BookService对象,并且定义一个名称为findBookById()的方法。
package cn.edu.imust.controller;
import cn.edu.imust.domain.Book;
import cn.edu.imust.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class BookController {
@Autowired
private BookService bookService;
@RequestMapping("/book")
public ModelAndView findBookById(Integer id){
Book book = bookService.findBookById(id);
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("book.jsp");
modelAndView.addObject("book",book);
return modelAndView;
}
}
14.1.3 Spring和MyBatis整合
Spring和MyBatis的整合可以分为2步来完成,首先搭建Spring环境,然后整合MyBatis到Spring环境中。
框架环境包含框架对应的依赖和配置文件,其中Spring的依赖、MyBatis的依赖、Spring和MyBatis整合的依赖,在项目基础结构搭建时候已经引入到项目中了,接下来,只需编写Spring的配置文件、Spring和MyBatis整合的配置文件即可。
1.Spring的配置文件
在项目的src/main/resources目录下,创建配置文件application-service.xml,用于配置Spring对Service层的扫描信息。application-service.xml具体代码如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!--开启注解扫描, 扫描包-->
<context:component-scan base-package="cn.edu.imust.service"/>
</beans>
2.Spring和MyBatis整合的配置
Spring和MyBatis的整合包中提供了一个SqlSessionFactoryBean对象,该对象的Bean需要注入数据源,也可以根据需求在SqlSessionFactoryBean的Bean中配置MyBatis核心文件路径、别名映射和Mapper映射文件路径。
在项目的src/main/resources目录下,创建数据源属性文件jdbc.properties,jdbc.properties配置的数据源信息如下所示。
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring?useUnicode=true\
&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=123456
接下来,将MyBatis整合到Spring的环境中。在src\main\resources目录下创建配置文件application-dao.xml,用于配置Spring和MyBatis整合信息。
application-dao.xml中包含的内容如下:
(1)引入属性文件;
(2)配置数据源;
(3)创建SqlSessionFactory对象;
(4)配置包扫描。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 引入属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- 数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<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>
<!-- 创建SqlSessionFactory对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 扫描Dao包,创建动态代理对象, 会自动存储到spring IOC容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定要扫描的dao的包 -->
<property name="basePackage" value="cn.edu.imust.dao"/>
</bean>
</beans>
3.整合测试:在项目的src/test目录下的java文件中,创建名称为BookServiceTest的测试类,用于对Spring和MyBatis的整合进行测试。
import cn.edu.imust.domain.Book;
import cn.edu.imust.service.BookService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:application-service.xml","classpath:application-dao.xml"})
public class BookServiceTest {
@Autowired
private BookService bookService;
@Test
public void findBookById(){
Book book = bookService.findBookById(1);
System.out.println("图书Id: " + book.getId());
System.out.println("图书名称:" + book.getName());
System.out.println("作者:" + book.getAuthor());
System.out.println("出版社:" + book.getPress());
}
}
运行测试方法findBookById(),方法运行后控制台打印信息如图所示。
从图中所示的信息可以看出,程序打印出了id为1的图书信息。这表明测试类中成功装配了BookService对象,BookService对象成功调用Service层的findBookById()方法,Service层的findBookById()方法成功调用Dao层的findBookById()方法完成了数据查询。说明Spring和MyBatis已经整合成功。
14.1.4 Spring和Spring MVC整合
1.Spring的配置
之前Spring和MyBatis整合时,已经完成了Spring的配置文件,Spring和Spring MVC整合,只需在项目启动时加载Spring容器和Spring的配置文件即可。
在项目的web.xml文件中配置Spring的监听器来加载Spring容器及Spring的配置文件,具体配置如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--配置文件加载-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:application-*.xml</param-value>
</context-param>
<!--容器加载的监听器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--Spring MVC 前端控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!--初始化参数-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--项目启动时候,初始化前端控制器-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.Spring MVC的配置
本案例主要测试SSM整合的情况,因此在Spring MVC的配置文件中只配置SSM整合案例必须的配置。必须配置的项有以下2个。
配置包扫描,指定需要扫描到Spring MVC中的Controller层所在的包路径。
配置注解驱动,让项目启动时启用注解驱动,并且自动注册HandlerMapping和HandlerAdapter。 在项目的src\main\resources目录下创建Spring MVC的配置文件spring-mvc.xml。Spring-mvc.xml文件配置完成之后,在web.xml中配置Spring MVC的前端控制器,并在初始化前端控制器时加载Spring MVC的配置文件。 (有关web.xml中的内容,在上一步的内容中已经添加)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置要扫描的包 -->
<context:component-scan base-package="cn.edu.imust.controller"/>
<!-- 配置注解驱动 -->
<mvc:annotation-driven/>
</beans>
3.SSM框架整合测试
(1)在项目的src/main/webapp目录下,创建名称为book.jsp的文件,用于展示处理器返回的图书信息。
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head><title>图书信息查询</title></head>
<body>
<table border="1">
<tr>
<th>图书id</th>
<th>图书名称</th>
<th>出版社</th>
<th>作者</th>
</tr>
<tr>
<td>${book.id}</td>
<td>${book.name}</td>
<td>${book.press}</td>
<td>${book.author}</td>
</tr>
</table>
</body>
</html>
(2)将chapter14项目部署到Tomcat中,启动项目,在浏览器中访问地址http://localhost:8080/chapter14SSM/book?id=1来进行图书查询,页面显示效果如图所示。
从图中所示的信息可以看出,程序成功查询到了id为1的图书信息。表明Controller层成功将Service层获取的图书信息返回给页面了,由此可以得出SSM框架整合成功。
14.2 纯注解方式整合SSM框架
14.2.1 整合思路
使用注解整合SSM框架,其实就是使用配置类替代原来XML配置文件在项目的作用。在14.1节中,使用XML配置文件完成了SSM框架整合;使用到的XML配置文件具体如下:
1.application-dao.xml
application-dao.xml配置文件中配置的内容包含以下4项。
- 读取jdbc.properties文件中的数据连接信息。
- 创建Druid对象,并将读取的数据连接信息注入到Druid数据连接池对象中。
- 创建SqlSessionFactoryBean对象,将并将Druid对象注入到SqlSessionFactoryBean对象中。
- 创建MapperScannerConfigurer对象,并指定扫描的Mapper的路径。
2.application-service.xml
application-service.xml配置文件中只配置了包扫描,指定需要扫描到Spring 的Service层所在的包路径。
3.spring-mvc.xml
spring-mvc.xml配置文件中配置了Spring MVC扫描的包路径和注解驱动。
4.web.xml
web.xml配置文件配置了项目启动时加载的信息,包含如下3个内容。
- 使用
元素加载Spring配置文件application-service.xml和Spring整合Mybatis的配置文件application-dao.xml。 - Spring容器加载监听器。
- 配置Spring MVC的前端控制器。
注:可以将以上文件删掉,或者将内容注释掉,来做如下案例内容,完成纯注解SSM框架整合。
14.2.2 纯注解SSM框架整合
接下来,将项目中的XML配置文件删除,使用纯注解的配置类依次替换对应的XML文件内容,以完成纯注解的SSM框架整合。具体实现步骤如下所示。
1.在项目的src\main\java目录下创建路径为cn.edu.imust.config的包,用于存放项目中的配置类。
在该包中创建名称为JdbcConfig的类,用于获取数据库连接信息并定义创建数据源的对象方法。
在JdbcConfig类中,通过@PropertySource注解读取jdbc.properties文件中的数据库连接信息,并定义getDataSource()方法,用于创建DruidDataSource对象, 通过DruidDataSource对象返回数据库连接信息。
package cn.edu.imust.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
/*
等同于<context:property-placeholder location="classpath*:jdbc.properties"/>
*/
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {
/*
使用注入的形式,读取properties文件中的属性值,
等同于<property name="*******" value="${jdbc.driver}"/>
*/
@Value("${jdbc.driverClassName}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String userName;
@Value("${jdbc.password}")
private String password;
/*定义dataSource的bean, 等同于
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
*/
@Bean("dataSource")
public DataSource getDataSource(){
//创建对象
DruidDataSource ds = new DruidDataSource();
/*
等同于set属性注入<property name="driverClassName" value="driver"/>
*/
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
}
2.在cn.edu.imust.config包中创建名称为MyBatisConfig的类,在MyBatisConfig类中定义getSqlSessionFactoryBean()方法,用于创建SqlSessionFactoryBean对象并返回;定义getMapperScannerConfigurer()方法,用于创建getMapperScannerConfigurer对象并返回。
package cn.edu.imust.config;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
public class MyBatisConfig {
/*
定义MyBatis的核心连接工厂bean,
等同于<bean class="org.mybatis.spring.SqlSessionFactoryBean">
参数使用自动装配的形式加载dataSource,
为set注入提供数据源,dataSource来源于JdbcConfig中的配置
*/
@Bean
public SqlSessionFactoryBean getSqlSessionFactoryBean(@Autowired DataSource dataSource){
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
//等同于<property name="dataSource" ref="dataSource"/>
ssfb.setDataSource(dataSource);
return ssfb;
}
/*
定义MyBatis的映射扫描,
等同于<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
*/
@Bean
public MapperScannerConfigurer getMapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
//等同于<property name="basePackage" value="cn.edu.imust.dao"/>
msc.setBasePackage("cn.edu.imust.dao");
return msc;
}
}
3.在cn.edu.imust.config包中,创建名称为SpringConfig的类作为项目定义Bean的源头,并扫描Service层对应的包。
package cn.edu.imust.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
//将MyBatisConfig类和JdbcConfig类交给Spring管理
@Import({MyBatisConfig.class,JdbcConfig.class})
//等同于<context:component-scan base-package="cn.edu.imust.service">
@ComponentScan(value = "cn.edu.imust.service")
public class SpringConfig {
}
4.在cn.edu.imust.config包中,创建名称为SpringMvcConfig的类作为Spring MVC的配置类,在配置类中指定Controller层的扫描路径。
package cn.edu.imust.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
//等同于<context:component-scan base-package="cn.edu.imust.controller"/>
@ComponentScan("cn.edu.imust.controller")
//等同于<mvc:annotation-driven/>,还不完全相同
@EnableWebMvc
public class SpringMvcConfig {
}
5.在cn.edu.imust.config包中,创建名称为ServletContainersInitConfig的类,继承AbstractAnnotationConfigDispatcherServletInitializer抽象类,重写抽象类的方法。用于替代之前web.xml文件配置的信息 ,初始化Servlet容器时加载指定初始化的信息。
package cn.edu.imust.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class ServletContainersInitConfig extends
AbstractAnnotationConfigDispatcherServletInitializer {
/*
加载Spring配置类中的信息,
初始化Spring容器
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
/*
加载Spring MVC配置类中的信息,
初始化Spring MVC容器
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
//配置DispatcherServlet的映射路径
@Override
protected String[] getServletMappings() {
System.out.println("纯注解方式整合SSM框架");
return new String[]{"/"};
}
}
至此,纯注解的SSM框架整合已经完成。
AbstractAnnotationConfigDispatcherServletInitializer抽象类
Spring提供了一个抽象类AbstractAnnotationConfigDispatcherServletInitializer,任意继承该抽象类的类都会在项目启动时自动创建DispatchServlet、初始化SpringMVC容器和Spring容器。
在项目中,可以通过继承该抽象类来设置DispatchServlet的映射路径,加载SpringMVC配置类到SpringMVC容器,并加载Spring配置类信息到Spring容器。
重写AbstractAnnotationConfigDispatcherServletInitializer抽象类的3个方法。
- getRootConfigClasses()方法:将Spring配置类的信息加载到Spring容器中。
- getServletConfigClasses()方法:将Spring MVC配置类的信息加载到Spring MVC容器中。
- getServletMappings()方法:可以指定DispatcherServlet的映射路径。
6.启动项目,在浏览器中访问图书信息查询地址,地址为http://localhost:8080/chapter14SSM/book?id=1,页面显示效果如图所示。