前言

要求:

  • 需要掌握 Spring、SpringMVC、MyBatis 这些主流开发框架
  • 了解 三层架构 和 MVC 架构模式

可以参考之前的笔记:

一、SSM 整合理解

1. 什么是 SSM 整合

SSM 整合就是将 Spring、SpringMVC、MyBatis 框架应用到项目中
采用三层架构 + MVC 模式分层:

  • Spring 负责模型层(业务逻辑层、数据访问层)
  • SpringMVC 负责控制层、表示层
  • MyBatis 负责数据访问层

Spring 接管一切

  • 将框架核心组件交给 Spring 进行 IoC 管理
  • Spring 管理业务逻辑层、数据访问层、以及数据库相关组件(DataSource、MyBatis)

实现:编写配置类,实现 SpringIoC 容器接管一切组件

2. 关于整合的容器

创建两个 IoC 容器:web 容器和 root 容器,组件分类管理

容器 盛放的组件
web 容器(子容器) web 相关组件(Controller、SpringMVC)
root 容器(父容器) 业务层和持久层相关组件 (Service、AOP、TX、DataSource、MyBatis、Mapper)

如图:

3. IoC 容器对应配置类

配置类 对应内容 对应容器
WebJavaConfig Controller,SpringMVC web 容器
ServiceJavaConfig Service,TX root 容器
MapperJavaConfig
DataSourceConfig
Mapper,Datasource,Mybatis root 容器

4. IoC 容器初始化

使用配置类的方式,进行 IoC 容器配置
图解:

二、代码实现(全注解开发)

1. 依赖整合

spring

  • ioc/di
    • spring-context
    • jakarta.annotation-api(JSR 250 使用 @Resource 注解)
  • aop
    • spring-aspects
  • tx
    • spring-tx
    • spring-jdbc

springmvc

  • spring-webmvc
  • jakarta.jakartaee-web-api
  • jackson-databind
  • hibernate-validator / hibernate-validator-annotation-processor(参数校验注解)

mybatis

  • mybatis
  • mysql
  • pagehelper

整合需要

  • spring-web(加载 spring 容器)
  • mybatis-spring(整合 mybatis)
  • druid(数据库连接池)
  • lombok
  • logback

pom.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.shameyanng</groupId>
<artifactId>ssm-integration</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>

<dependencies>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.1.4</version>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>1.3.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>6.0.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>6.1.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>6.1.4</version>
</dependency>
<!-- springmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>6.1.4</version>
</dependency>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version>10.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>8.0.1.Final</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.2.0</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.3</version>
</dependency>
<!-- 整合第三方依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>6.1.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.14</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

2. 控制层配置

WebJavaConfig:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* @author ShameYang
* @date 2023/11/13 11:33
* @description Controller,SpringMVC 相关组件配置
* 1.实现 SpringMVC 组件声明标准化接口 WebMvcConfigurer 提供了各种组件对应的方法
* 2.添加配置类注解 @Configuration
* 3.添加 MVC 复合功能开关 @EnableWebMvc
* 4.添加 Controller 层扫描注解
* 5.开启默认处理器,支持静态资源处理
*/
@Configuration
@EnableWebMvc
@ComponentScan("com.shameyang.controller")
public class WebJavaConfig implements WebMvcConfigurer {
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}

3. 业务层配置

ServiceJavaConfig:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* @author ShameYang
* @date 2023/11/13 11:40
* @description service,aop 和声明事务相关配置
* 1. @Configuration 注解,代表配置类
* 2. @EnableTransactionManagement 注解,开启事务注解支持
* 3. @EnableAspectJAutoProxy 注解,开启 aspect aop 注解支持
* 4. @ComponentScan("com.shameyang.service") 注解,进行业务组件扫描
* 5. transactionManager(DataSource dataSource) 方法,指定具体的事务管理器
*/
@EnableTransactionManagement
@EnableAspectJAutoProxy
@Configuration
@ComponentScan("com.shameyang.service")
public class ServiceJavaConfig {
@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}

4. 持久层配置

MapperJavaConfig:注入 SqlSessionFactory 和 Mapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@Configuration
public class MapperJavaConfig {
// 注入 SqlSessionFactoryBean
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
// 实例化 SqlSessionFactory 工厂
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
// 设置连接池
sqlSessionFactoryBean.setDataSource(dataSource);
// settings
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
configuration.setMapUnderscoreToCamelCase(true);
configuration.setLogImpl(Slf4jImpl.class);
configuration.setAutoMappingBehavior(AutoMappingBehavior.FULL);
sqlSessionFactoryBean.setConfiguration(configuration);
// typeAliases
sqlSessionFactoryBean.setTypeAliasesPackage("com.shameyang.pojo");
// 分页插件配置
PageInterceptor pageInterceptor = new PageInterceptor();
Properties properties = new Properties();
properties.setProperty("helperDialect", "mysql");
pageInterceptor.setProperties(properties);
sqlSessionFactoryBean.addPlugins(pageInterceptor);
return sqlSessionFactoryBean;
}

// 注入 Mapper 映射器
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
// 配置需要扫描的 mapper 包
mapperScannerConfigurer.setBasePackage("com.shameyang.mapper");
return mapperScannerConfigurer;
}
}

DataSourceConfig:注入 DataSource

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Configuration
@PropertySource("classpath:jdbc.properties") // 指定 jdbc 配置文件的位置
public class DataSourceJavaConfig {
@Value("${jdbc.user}")
private String user;
@Value("${jdbc.password}")
private String password;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.driver}")
private String driver;

// 配置数据源
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername(user);
dataSource.setPassword(password);
dataSource.setUrl(url);
dataSource.setDriverClassName(driver);
return dataSource;
}
}

5. 容器初始化配置

SpringIoCInit:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class SpringIoCInit extends AbstractAnnotationConfigDispatcherServletInitializer {
// 指定 root 容器对应的配置类
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{MapperJavaConfig.class, ServiceJavaConfig.class, DataSourceJavaConfig.class};
}

// 指定 web 容器对应的配置类
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebJavaConfig.class};
}

//指定 dispatcherServlet 处理路径,通常为 /
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}