一、事务
1.事务的实现方式
1.编程式事务,也就是手动操作事务
开启事务
TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
提交事务
transactionManager.commit(transactionStatus);
回滚事务
transactionManager.rollback(transactionStatus);
2.声明式事务
声明式事务管理则通过注解或XML配置的方式将事务管理代码与业务代码分离,在需要事务支持的方法或类上添加@Transactional
注解,无需手动开启事务和提交事务
2.事务的传播行为
- PROPAGATION_REQUIRED(默认):
- 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
- 这是最常见的选择,也是Spring默认的事务传播行为。
- PROPAGATION_SUPPORTS:
- 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。
- 这种方法对于那些不需要事务也能正确执行,但在事务环境下运行也不会造成任何问题的方法特别有用。
- PROPAGATION_MANDATORY:
- 支持当前事务,如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
- 这种行为要求被调用的方法必须在一个已存在的事务中执行。
- PROPAGATION_REQUIRES_NEW:
- 创建一个新的事务,如果当前存在事务,则把当前事务挂起。
- 这种行为确保了被调用的方法将在一个全新的事务中执行,与调用者的事务相互独立。
- PROPAGATION_NOT_SUPPORTED:
- 以非事务方式执行操作,如果当前存在事务,则把当前事务挂起。
- 这种行为使得被调用的方法将不会参与到任何事务中,无论当前是否存在事务。
- PROPAGATION_NEVER:
- 以非事务方式执行,如果当前存在事务,则抛出异常。
- 这种行为表明被调用的方法不应该在事务环境中执行,如果当前存在事务,则会抛出异常。
- PROPAGATION_NESTED:
- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则等同于PROPAGATION_REQUIRED。
- 嵌套事务可以独立于父事务进行提交或回滚,而不会影响父事务的状态。
3.事务的隔离级别
读未提交(Read Uncommitted)
一个事务能够读取到别的事务中没有提交的更新数据。事务中的修改,即使没有提交,其他事务也可以看得到。在这种隔离级别下有可能发生脏读,不可重复读和幻读。
读已提交(Read Committed)
事务中的修改只有提交以后才能被其它事务看到。在这种隔离级别下解决了脏读,但是有可能发生不可重复读和幻读。
可重复读(Repeated Read)
保证了在同一事务中先后执行的多次查询将返回同一结果,看到的每行的记录的结果是一致的,不受其他事务的影响。但是这种级别下有可能发生幻读。
串行化(Serializable)
不允许事务并发执行,强制事务串行执行。就是在读取的每一行数据上都加上了锁,读写相互都会阻塞,所以效率很低下。这种隔离级别最高,是最安全的,但是性能最低,不会出现脏读,不可重复读,幻读。
4.spring事务和springboot事务的区别
Spring Boot事务和Spring事务在本质上是相同的,然而,Spring Boot通过自动配置和约定优于配置的原则,进一步简化了事务管理的使用,使得开发者能够更加轻松地实现事务控制。
5.判断哪一条事务进行了回滚
(1)通过查看springboot日志和数据库日志
(2)异常处理
检查异常捕获点:查看每条执行语句后是否有异常捕获逻辑。如果某个语句后的异常被捕获且未重新抛出(特别是未抛出RuntimeException或Error),则可能导致该语句所在的事务不回滚。
分析异常类型:注意异常的类型,因为Spring Boot默认只对RuntimeException和Error进行事务回滚。如果捕获了其他类型的异常(如checked异常),并且没有显式地回滚事务,则事务可能不会被回滚。
(3)事务同步与回调
使用TransactionSynchronizationManager
注册事务同步回调,可以在事务提交或回滚时执行特定的逻辑。
二、SpringBoot注解
核心注解
1. @SpringBootApplication
- 这是一个方便的注解,包含了`@SpringBootConfiguration`、`@EnableAutoConfiguration`、`@ComponentScan`。它通常用在 Spring Boot 应用的入口类上,标记这个类为 Spring Boot 的应用类。
2. @SpringBootConfiguration
- 表明当前类是一个配置类,等同于 Spring 的`@Configuration`注解。但它被`@SpringBootApplication`注解所隐含。
3. @EnableAutoConfiguration
- 告诉 Spring Boot 基于添加的 jar 依赖自动配置 Spring 应用。比如,如果 classpath 下存在 HSQLDB,并且你没有手动配置任何数据库连接 bean,那么 Spring Boot 会自动配置一个内存型数据库。
4. @ComponentScan
- 让 Spring 扫描到配置类所在的包及其子包下的所有带有`@Component`、`@Service`、`@Repository`等注解的类,并注册为 Spring 应用上下文中的 Bean。
常用注解
-
@RestController
-
这是一个组合注解,相当于
@Controller
和@ResponseBody
的结合体,用于定义 REST 控制器。
-
-
@RequestMapping
-
用于将 HTTP 请求映射到特定的处理器方法上。可以指定请求方法(GET、POST 等)、路径等。
-
-
@GetMapping、@PostMapping、@PutMapping、@DeleteMapping
-
这些是
@RequestMapping
的特定 HTTP 方法变体,用于简化开发。
-
-
@PathVariable
-
用于将 URL 模板变量绑定到处理器方法的参数上。例如,
@GetMapping("/user/{id}")
配合@PathVariable("id") Long id
可以将 URL 中的{id}
部分绑定到id
参数上。
-
-
@RequestParam
-
用于将请求参数绑定到控制器处理方法的参数上。例如,
@RequestParam("name") String name
。
-
-
@Autowired
-
自动装配 Spring 应用上下文中的 Bean。可以用在字段、构造函数或配置方法上。
-
-
@Service
-
标注在业务层组件上,表示这是一个服务层组件。虽然
@Service
没有提供额外功能(它本质上是一个@Component
),但它是一个很好的实践,有助于区分组件的用途。
-
-
@Repository
-
标注在数据访问层组件上,表示这是一个数据访问层组件(如 DAO)。和
@Service
一样,它也是一个@Component
的特殊化。
-
-
@Value
-
注入配置文件中的值(如 application.properties 或 application.yml)到字段中。
-
-
@Profile
-
用于指定某个配置类或配置方法只在特定的环境配置下才激活。
-
-
@Entity、@Id
-
这些是 JPA 的注解,用于定义实体类、主键及主键的生成策略等。虽然它们不是 Spring Boot 特有的,但在 Spring Boot 应用中使用 JPA 时非常常见。
-
三.Spring
1.IOC和AOP
IOC:(Inverse of Control)控制反转,也叫DI依赖注入,指的是将对象的创建权交给 Spring 容器去创建,利用了工厂模式将对象交给容器管理,只需要在spring配置文件总配置相应的bean,以及设置相关的属性,让spring容器来生成类的实例对象以及管理对象。不需要我们手动new去创建对象,大大降低了代码间的耦合度,使资源更加容易管理。
AOP:(Aspect Oriented Programming)面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。 AOP可以分离业务代码和关注点代码(重复代码),在执行业务代码时,动态的注入关注点代码。切面就是关注点代码形成的类。Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。
2.Bean的作用域
1. singleton(单例作用域)
-
定义:默认的作用域。在Spring IoC容器中,对于该作用域下的Bean,仅存在一个Bean实例,即所有对该Bean的请求都返回同一个Bean实例。
-
特点:Bean实例在容器启动时创建,并在整个应用的生命周期内共享。适用于无状态的Bean,如服务类和工具类。
-
示例:使用
@Component
或@Bean
注解定义的Bean,如果未指定作用域,则默认为singleton。
2. prototype(原型作用域)
-
定义:每次对该作用域下的Bean的请求都会创建一个新的Bean实例。
-
特点:适用于有状态的对象,如用户会话信息。每次请求Bean时都会创建一个新的实例,因此可以保持请求间的隔离性。
-
示例:使用
@Scope("prototype")
注解定义的Bean。
3. request(请求作用域)
-
定义:每个HTTP请求都会创建一个新的Bean实例,该Bean实例仅在当前请求内有效。
-
特点:适用于Web应用程序,每个请求都有独立的Bean实例。请求结束后,Bean实例会被销毁。
-
示例:在Spring MVC中,控制器(Controller)可以使用request作用域,以确保每个请求都有独立的控制器实例。
4. session(会话作用域)
-
定义:每个HTTP会话都会创建一个新的Bean实例,该Bean实例仅在当前会话内有效。
-
特点:适用于需要在用户会话期间保持状态的对象,如用户登录信息。会话结束时,Bean实例会被销毁。
-
示例:在Spring MVC中,可以使用session作用域来存储用户会话信息。
5. application(全局作用域)
-
定义:在ServletContext的生命周期内共享一个Bean实例。
-
特点:适用于整个Web应用程序范围内共享状态的Bean,如应用程序的共享信息。
-
示例:使用
@Scope("application")
注解定义的Bean。
6. websocket(HTTP WebSocket 作用域)
-
定义:在WebSocket的生命周期内,定义一个Bean实例。
-
特点:适用于WebSocket通信场景,每个WebSocket连接都有独立的Bean实例。
-
示例:在Spring WebSocket应用中,可以使用websocket作用域来管理WebSocket相关的资源。
3.注入歧义性
在进行自动装配中,Spring 发现存在多个符合依赖条件的 bean 时,会产生歧义性,并抛出异常。
1使用@Qualifier注解:在自动装配时,可以通过@Qualifier
注解来指定要注入的Bean的名称,从而解决歧义性。例如:
@Autowired
@Qualifier("specificBeanName")
private MyBean myBean;
2.使用@Primary注解:如果大多数情况下都希望注入某个特定的Bean,可以使用@Primary
注解将该Bean标记为首选的Bean。这样,在存在多个候选Bean时,Spring容器会优先注入被标记为@Primary
的Bean。但需要注意的是,@Primary
注解不能解决多个相同首选Bean的情况。
3.使用@Resource
注解(默认按名称注入)来实现。
四.Springboot启动,打包,部署
1、Spring Boot启动
Spring Boot的启动过程大致可以分为以下几个步骤:
-
寻找主类:SpringBoot项目启动时,它会在当前工作目录下寻找带有
@SpringBootApplication
注解标识的类,并把这个类作为应用程序的入口点。如果找不到这样的主类,则会打印错误信息并退出。 -
加载配置:使用
SpringFactoriesLoader
加载监听器,如EventPublishingRunListener
。SpringBoot会自动扫描当前项目的resources
目录,并加载其中的application.properties
或application.yml
等配置文件。这些配置文件中包含了应用程序的各种参数,例如数据库连接信息、日志级别等。 -
创建和配置环境:创建和配置
Environment
,该对象包含了应用程序的运行环境信息。 -
初始化ApplicationContext:根据项目类型(Web、Reactive、非Web)创建相应的
ApplicationContext
实例,扫描当前项目中的所有Bean,并将它们注册到ApplicationContext
中。加载自动配置,根据starter依赖中的Configuration
和Bean的装配情况,自动装配相应的Bean。 -
启动Web容器:如果项目是一个Web应用,SpringBoot会根据配置文件中的信息自动创建Tomcat或Jetty等Web容器,并将Spring容器注册到Web容器中,使得SpringBoot应用程序可以直接以Web应用程序的形式运行。
-
启动服务:根据之前创建好的Spring容器以及Web服务器,启动相应的线程进行服务处理。SpringBoot会监听应用程序的状态,并根据需要进行相应的操作。例如,当应用程序退出时,它会打印出详细的日志信息,并将应用程序的上下文环境恢复到初始状态。
-
发布事件:在启动的不同阶段,SpringBoot会发布各种事件,如
started()
、ready()
等,允许开发者在特定的时间点执行自定义的逻辑。
2、Spring Boot打包
Spring Boot支持多种打包方式,常见的有Jar包和War包两种方式。
- Jar包方式:
- 添加Maven插件(
spring-boot-maven-plugin
)到pom.xml
文件中。 - 修改打包方式为jar,并配置相关的项目信息。
- 执行Maven打包命令(
mvn clean package
),生成的jar包会位于target
目录下。
- 添加Maven插件(
- War包方式(适用于需要将Spring Boot应用部署到外部Servlet容器的情况):
- 修改
pom.xml
文件中的<packaging>
标签为war
。 - 添加Tomcat服务器依赖,并设置为
provided
范围,以便在打包时排除自带的Tomcat。 - 修改启动类,使其继承
SpringBootServletInitializer
并重写configure
方法。 - 执行Maven打包命令(
mvn clean package
),生成的war包会位于target
目录下。
- 修改
3、Spring Boot部署
部署Spring Boot应用的方式取决于打包方式和目标环境。
- Jar包部署:
- 将打包好的jar包复制到目标服务器上。
- 确保服务器上已安装JDK,并且版本与项目要求一致。
- 打开命令行工具,进入jar包所在目录。
- 执行
java -jar jar包名称.jar
命令启动应用。
- War包部署:
- 将打包好的war包复制到Tomcat服务器的
webapps
目录下。 - 启动Tomcat服务器,Tomcat会自动解压war包并部署应用。
- 访问应用的URL(如
http://localhost:8080/应用名/
),验证应用是否成功部署。
- 将打包好的war包复制到Tomcat服务器的