1.SSM集成框架
1.1.SSM集成框架简介
1.1.1.为什么要使用SSM集成框架
时至今日,MVC三层架构仍然是我们开发应用程序时所采用的主流架构模式,而 SpringMVC 就是一款优秀的 MVC 框架。那么,为什么我们仍然要将 SpringMVC 与 Spring、MyBatis 集成在一起使用呢。
首先,SpringMVC 对持久层没有任何支持,所以持久层需要使用 MyBatis。其次,为了将 SpringMVC 和 MyBatis 所需组件解耦,需要由 Spring 为其注入。这就是为什么要 SSM 集成的原因。
1.1.2.SSM集成分析
简单来说:SSM集成就是使用 Spring 给 SpringMVC 和 MyBatis 注入所需要组件。
具体来说:SSM集成就是:
- 由 SpringMVC 负责搭建 MVC 架构,由 MyBatis 负责持久层。
- 由 Spring 给 SpringMVC 注入控制层组件、业务层组件、数据层组件等。
- 由 Spring 给 MyBatis 注入数据源、SqlSessionFactory、事务等。
1.2.SSM集成
1.2.1.创建Maven工程并添加依赖
在pom.xml文件中添加如下依赖<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.neusoft</groupId>
<artifactId>ssm</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<!-- 添加项目jdk编译插件 -->
<build>
<plugins>
<!-- 设置jdk版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<spring.version>5.2.8.RELEASE</spring.version>
</properties>
<dependencies>
<!-- 此依赖会关联引用Spring中的所有基础jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- SpringMVC的jar包 (会依赖spring-web)-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring支持jdbc的jar包(会依赖 spring-tx事务jar包) -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- aspectj依赖jar包 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
<!-- jackson依赖jar包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<!--mybatis 依赖包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!-- mybatis-spring 依赖包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.0</version>
</dependency>
<!-- mysql驱动 依赖包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
</dependencies>
</project>
1.2.2.加载Spring容器
在Web项目中,如果每次请求时都要读取 Spring 配置文件并加载 Spring 容器,将会很耗费资源。所以我们要在服务器启动时,就加载 Spring 容器。
所以,我们可以在 ServletContext 监听器中监听 服务器启动,然后加载 Spring 容器。而且,这个监听器 Spring已经做好了,我们只要在 web.xml 文件中配置即可。<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <!-- Spring整合web项目用的ServletContext监听器 --> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <!-- 指定spring配置文件路径,默认加载 /WEB-INF/applicationContext.xml --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> </web-app>
1.2.3.创建Spring容器
创建applicationContext.xml 配置文件,也就是 Spring 容器。<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" 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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 后面会陆续的添加内容 --> </beans>
1.2.4.集成MyBatis
1.2.4.1.创建Mapper接口
package com.neusoft.ssm.mapper; import org.apache.ibatis.annotations.Mapper; import com.neusoft.ssm.po.Dept; @Mapper public interface DeptMapper { public Dept getDeptById(Integer deptno); }
注意:Mapper接口需要使用 @Mapper 注解
1.2.4.2.创建映射文件
<?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="com.neusoft.ssm.mapper.DeptMapper">
<select id="getDeptById" parameterType="int" resultType="Dept">
select * from dept where deptno=#{deptno}
</select>
</mapper>
1.2.4.3.在Spring容器中配置MyBatis
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/emp?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123
<!-- 引入db配置文件 -->
<context:property-placeholder location="classpath:db.properties" />
<!-- 配置dataSource数据源 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 创建SqlSessionFactory,并配置实体对象别名 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="typeAliasesPackage" value="com.neusoft.ssm.po" />
</bean>
<!-- 配置Mapper。自动扫描Mapper接口,并为其注入SqlSessionFactory -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.neusoft.ssm.mapper"></property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
<!-- 配置Spring提供的事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开启注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
1.2.5.集成SpringMVC
实际上,Spring 框架中包含 SpringMVC ,所以 SpringMVC 本身不需要集成。所以,下面除了做SpringMVC的相关配置外,主要是注入 service 组件。
1.2.5.1.配置SpringMVC前端控制器
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--使⽤Rest风格的URI,将页⾯普通的post请求转为指定的delete或者put请求,可选的配置-->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<servlet-name>springmvc</servlet-name>
</filter-mapping>
<filter>
<filter-name>HttpPutFormContentFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpPutFormContentFilter</filter-name>
<servlet-name>springmvc</servlet-name>
</filter-mapping>
1.2.5.2.创建SpringMVC配置文件
创建springmvc-servlet.xml 配置文件,也就是 SpringMVC的配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="com.neusoft.ssm.controller" />
</beans>
1.2.5.3.创建service组件
package com.neusoft.ssm.service;
import com.neusoft.ssm.po.Dept;
public interface DeptService {
public Dept getDeptById(Integer deptno);
}
package com.neusoft.ssm.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.neusoft.ssm.mapper.DeptMapper;
import com.neusoft.ssm.po.Dept;
import com.neusoft.ssm.service.DeptService;
@Service
public class DeptServiceImpl implements DeptService{
@Autowired
private DeptMapper deptMapper;
@Override
@Transactional
public Dept getDeptById(Integer deptno) {
return deptMapper.getDeptById(deptno);
}
}
注意:
- 使用 @Service 注解标识这是一个 service 组件。
- 使用 @Autowired 注解自动注入 mapper 组件。
1.2.5.3.创建SpringMVC处理器
package com.neusoft.ssm.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.neusoft.ssm.po.Dept;
import com.neusoft.ssm.service.DeptService;
@Controller
public class DeptController {
@Autowired
private DeptService deptService;
@ResponseBody
@RequestMapping("/getDeptById")
public Dept getDeptById(Integer deptno) throws Exception{
return deptService.getDeptById(deptno);
}
}
注意:使用 @Autowired 注解注入 service 组件。
1.2.5.4.在Spring容器中添加service组件
<context:component-scan base-package="com.neusoft.ssm.service" />
1.2.6.测试
至此,SSM集成完毕。整个工程的目录结构如下:
接下来,将此工程部署在Tomcat中,启动Tomcat,在浏览器地址栏中输入:http://localhost:8080/ssm/getDeptById?deptno=10 进行测试。
1.2.7.SSM中两个Spring容器的总结
- springmvc-servlet.xml:这是SpringMVC框架的专用Spring容器。所以这里只写与SpringMVC相关组件的配置。
- applicationContext.xml:这是整个工程的Spring容器。所以,除了SpringMVC之外的其它组件,都要配置在这里。比如:dao、service、事务等等。
-
2.纯注解式SSM集成
时下还是非常流行注解方式编程的,那么下面就使用纯注解的方式实现SSM集成。
所谓纯注解方式就是:除了pom.xml文件外,工程中没有任何一个配置文件。2.1.创建Maven工程并添加依赖
pom.xml文件中的内容同上。只是添加一个servlet-api的依赖即可:
<project> <!-- 同上 --> <dependencies> <!-- 同上 --> <!-- 增加servlet-api依赖 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.0</version> <scope>provided</scope> </dependency> </dependencies> </project>
2.2.创建工程总配置类
在类路径下创建AppInitializer.java文件
package com.neusoft.ssma; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{ /** * 返回一个带有@Configuration注解的类。 * 用来创建整个应用程序的全局Spring容器。 * 也就是等同于创建applicationContext.xml容器 */ @Override protected Class<?>[] getRootConfigClasses() { return new Class[] {RootConfig.class}; } /** * 返回一个带有@Configuration注解的类。 * 用来创建SpringMVC(即Web相关)的Spring容器。 * 也就是等同于创建springmvc-servlet.xml容器 */ @Override protected Class<?>[] getServletConfigClasses() { return new Class[] {WebConfig.class}; } //配置SpringMVC前端控制器映射路径 @Override protected String[] getServletMappings() { return new String[] {"/"}; } }
在servlet3.0以上环境中,web容器会在类路径中查找实现了javax.servlet.ServletContainerInitializer接口的类,如果能找到此类就会用它来配置Servlet容器。
Spring3.2之后,提供了这个接口的实现,它是一个抽象类:AbstractAnnotationConfigDispatcherServletInitializer。
要实现AbstractAnnotationConfigDispatcherServletInitializer的三个抽象方法: getRootConfigClasses:用来创建整个应用程序的全局Spring容器(等同于applicationContext.xml)。
- getServletConfigClasses:用来创建SpringMVC(即Web相关)的Spring容器。(等同于springmvc-servlet.xml)
- getServletMappings:配置SpringMVC前端控制器映射路径(SpringMVC前端控制器已自动注入)。
总结:AppInitializer.java就相当于:web.xml + applicationContext.xml + springmvc-servlet.xml
2.3.创建Spring容器配置类
在类路径下创建RootConfig.java文件,它就相当于applicationContext.xml。
package com.neusoft.ssma;
import javax.sql.DataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
//@ComponentScan用于扫描通用组件,这里用来扫描Service组件
@ComponentScan(basePackages={"com.neusoft.ssma.service"})
//@MapperScan用于扫描Mapper组件
@MapperScan(basePackages="com.neusoft.ssma.mapper")
public class RootConfig {
//创建dataSource组件并放入Spring容器
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/emp?characterEncoding=utf-8");
dataSource.setUsername("root");
dataSource.setPassword("123");
return dataSource;
}
//创建SqlSessionFactory组件并放入Spring容器
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
return sqlSessionFactoryBean;
}
//创建PlatformTransactionManager组件并放入Spring容器
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
//dataSource也可以通过参数注入
return new DataSourceTransactionManager(dataSource());
}
}
2.4.创建Web相关Spring容器
在类路径下创建WebConfig.java文件,它就相当于springmvc-servlet.xml。
package com.neusoft.ssma;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
//SpringMVC注解,等同于<mvc:annotation-driven/>
@EnableWebMvc
//@ComponentScan用于扫描通用组件,这里用来扫描Controller组件
@ComponentScan(basePackages={"com.neusoft.ssma.controller"})
public class WebConfig{ }
2.5.创建其它组件
Controller组件、Service组件、Mapper组件同上,没有任何变化。
2.6.测试
至此,纯注解式SSM集成完毕。整个工程的目录结构如下:
接下来,将此工程部署在Tomcat中,启动Tomcat,在浏览器地址栏中输入:http://localhost:8080/ssm/getDeptById?deptno=10 进行测试。
3.注解和XML
- 注解:是一种分散式的元数据,与源代码紧绑定。
- xml:是一种集中式的元数据,与源代码无绑定。
元数据:描述数据的数据
3.1.XML的优点与缺点
- 优点:
- xml是集中式的元数据,不需要和代码绑定的
- 更具有扩展性。修改配置时只需要修改xml即可,不需要对现有的程序进行修改
- 组件之间的关系一目了然
- 有成熟的校验机制来保证正确。比如使用Schema或者是DTD来对xml的正确性进行校验
缺点:
优点:
- 简化了XML配置,使用起来更直观
- 类型安全,编译期即可验证正确性。XML只能在运行期才能发现问题
- 只维护代码即可,不用再维护其它文件
缺点:
Spring 在SSM中起什么作用?
- 在SSM中还需要MyBatis配置文件吗?
- SSM中两个Spring容器的作用分别是什么?
- 什么是纯注解式SSM集成?
- 在纯注解式SSM集成中的配置入口是什么?
- AbstractAnnotationConfigDispatcherServletInitializer的三个抽象方法的作用是什么?
- 到底是使用xml配置方式,还是纯注解式来实现SSM集成?
- 编程题:
- 使用SSM集成框架实现一个登录案例。
- 使用前后端分离的模式实现。
- 服务器端要有数据层组件、业务层组件、控制层组件。
- 数据层组件使用MyBatis框架完成对数据库的操作。
- 控制层组件要向前端返回json数据。
- 前端使用ajax请求,并通过服务器端返回的json数据来判断是否登录成功。