【SSM】篇三:Spring事务和SpringMVC入门案例
文章目录
1、Spring事务
1.1 Spring事务简介
- 事务的作用:在数据层保障一系列的数据库操作同时成功或者同时失败
- Spring事务作用:在数据层或业务层保障一系列的数据库操作同时成功或者同时失败
Spring中的相关接口和实现类:
案例:模拟银行账户间转账业务
需求:实现任意两个账户间转账
库表:t_act
业务层和数据层接口:
业务层实现类:
未开启事务的情况下,模拟转账异常(使用10/0),测试:
出现丢钱的情况:
STEP1:在业务层接口添加Spring事务管理
@Transactional
public interface AccountService{
public void transfer(String out,String in,Double money);
}
- Spring注解式事务通常添加在业务层接口中,而不会添加到业务层实现类中,降低耦合
- 注解式事务可以添加到某个方法上,表示当前方法开启事务,也可添加到接口上,表示接口中的所有方法开启事务
STEP2:设置平台事务管理器
STEP3:开启注解式事务驱动
在Spring配置类SpringConfig.class中加入:
@EnableTransactionManagement
1.2 Spring事务角色
- 事务管理员:发起事务方,在Spring中通常指代业务层开启事务的方法
- 事务协调员:加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法
未加入Spring事务之前:
加入@Transactional
1.3 Spring事务配置
有些异常默认不参与回滚,需要手动加,比如IOException:
由于IOException默认不参加回滚,此时即使开启Spring事务,也会丢钱。需手动在rollbackfor属性加一下:
其余属性:
案例--转账业务追加日志
代码实现:
定义数据层和业务层:
业务层实现类:
为实现"不论转账是否成功,均有日志留痕",将日志语句放在finally中:
运行后发现,发生异常后,日志并未写入
原因分析:
事务管理员和事务协调当前是一个整体,
而我需要日志记录是另一个单独的事务。这样,上面的账户事务回滚的时候,日志事务不回滚
事务的传播行为:
事务协调员对事务管理员所携带事务的处理态度,即你开启事务了,我是加入呢?不加入呢?还是自己开一个事务呢。通过在Transactional注解的Propagation属性进行说明。
各个取值含义:
此时,发生异常,log数据表中正常记录:
2、SpringMVC
2.1 SpringMVC简介
SpringMVC技术和Servlet技术功能等同,均属于web层开发技术,是一种基于JAVA的轻量级Web框架。
使用Servlet:
使用SpringMVC:
2.2 SpringMVC入门案例
步骤:
STEP1:导入SpringMVC坐标与Servlet坐标
STEP2:创建SpringMVC控制器类(等同于Servlet功能)
STEP3:初始化SpringMVC环境
这里和Spring一样,写配置类,加载对应的bean
STEP4:告诉TomCat加载SpringMVC环境
初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求
相关注解:
- 名称:@Controller
- 类型:类注解
- 位置:SpringMVC控制器类定义的上方
- 作用:设定SpringMVC核心控制器bean
@Controller
public class UserController{
}
- 名称:@RequestMapping
- 类型:方法注解
- 位置:SpringMVC控制器方法定义的上方
- 作用:设定当前控制器方法的访问路径
@Controller
public class UserController{
@RequestMapping("/save")
public void save(){
System.out.println("save ...");
}
}
- 名称:@ResponseBody
- 类型:方法注解
- 位置:SpringMVC控制器方法定义的上方
- 作用:设定当前控制器方法响应内容为当前返回值,无需解析
@Controller
public class UserController{
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("save ...");
return "{'code':'9527'}";
}
}
代码实现:
控制器类:
package com.llg.controller;
import ...
@Controller
public class UserController {
/**
* RequestMapping注解设置当前操作的访问路径
* ResponseBody注解设置当前操作的返回值类型
* @return
*/
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("User save ...");
return "{'module':'SpringMVC'}";
}
@RequestMapping("/code")
@ResponseBody
public String code(){
System.out.println("code ...");
return "{'code':'9527'}";
}
}
写配置类,加载bean:
package com.llg.config;
import ...
@Configuration
@ComponentScan("com.llg.controller")
public class SpringMvcConfig {
}
初始化Servlet容器,加载SpringMVC环境:
package com.llg.config;
import ...
/**
* 定义servlet容器启动配置类,在里面加载Spring的配置
* @author LLG
* @date 2023/3/13
*/
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
/**
* 加载SpringMVC容器配置的
* @return
*/
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
/**
* 设置哪些请求归属SpringMVC处理
* /表示拦截所有请求,任意请求都转入到SpringMVC处理
* @return
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
/**
* 加载Spring容器的配置
* @return
*/
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
pom文件中加入tomcat插件:
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/</path> <!-- 项目访问路径 本例:localhost:9090, 如果配置的aa,则访问路径为localhost:9090/aa -->
<port>9090</port>
<uriEncoding>UTF-8</uriEncoding><!-- 非必需项 -->
</configuration>
</plugin>
</plugins>
</build>
工作流程分析:
2.3 bean加载控制
功能不同,如何避免Spring加载bean的时候错误的加载到SpringMVC的bean—加载Spring控制的bean的时候排除掉SpringMVC控制的bean
具体实现:
此时getBean就拿不到UserController类的bean了:
相关注解–@ComponentScan
- 名称:@ComponentScan
- 类型:类注解
- 属性:
。excludeFilters:排除扫描路径中加载的bean,需要指定类别type和具体项classes
。includeFilters:加载指定的bean,需要指定类别type和具体项classes
SpringMVC和Spring加载对应的bean:
在此基础上,做一个简化,去继承另一个类:
相关文章
- KubeSphere 社区双周报 | KubeKey v3.0.7 发布 | 2023-02-03
- 结构体和类的差异对比
- 【自动驾驶100问】第一问到第三问
- 【A】1.2 链表
- 铝型材加实木家具设计-工具篇(待更新,目前25%)
- Casbin: 连续3年参加Google Summer of Code的开源授权技术领导者
- 2022游戏体验
- 当你读懂老舍的《茶馆》,就看清了人生的三重境界
- 时间的悖论读书笔记
- 小白科普丨何为树、二叉树和森林?
- He3: 开发者和安全工作者的瑞士军刀
- 电商系统的高质量容量保障是怎样“炼成”的?
- 软件版本号规范
- 一文讲尽Thread类的源码精髓
- 手把手教大家写书写一个Mqtt网关
- 计算机与软件考研公众号博主推荐
- MATLAB环境中CVX安装外部Mosek求解器
- Windows喝水记录工具v2.0
- 文本纠错:提升OCR任务准确率的方法理解
- 云原生周刊 | 使用 K8s 可视化工具集来调试业务 | 2023-1-30