一图千言之spring模块组成
Transaction Management
全面的事务支持。Spring Framework 为事务管理提供了一致的抽象,具有以下优点
-
跨不同事务 API 的一致编程模型,例如 Java 事务 API (JTA)、JDBC、Hibernate 和 Java Persistence API (JPA)。
-
支持声明式事务管理。
-
比复杂的事务 API(例如 JTA)更简单的用于程序化事务管理的 API。
-
与 Spring 的数据访问抽象的完美集成
理解 Spring 框架事务抽象
public interface PlatformTransactionManager extends TransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
这主要是一个服务提供者接口 (SPI)。按照 Spring 的理念,
TransactionException
可以由任何PlatformTransactionManager
接口的方法抛出的 是未经检查的(即,它扩展了java.lang.RuntimeException
类)。
TransactionManager
实现通常需要了解它们工作的环境:JDBC、JTA、Hibernate 等等。以下示例展示了如何定义本地PlatformTransactionManager
实现(在本例中,使用普通 JDBC。)例子
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <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> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
Declarative Transaction Management
声明式事务对应用程序代码的影响最小,因此最符合非侵入式轻量级容器的理想。Spring框架的声明性事务支持是通过AOP代理启用的,而事务通知是由元数据驱动的(目前是基于XML或基于注释的)。AOP与事务性元数据的结合产生了一个AOP代理,该代理使用TransactionInterceptor和适当的TransactionManager实现来驱动围绕方法调用的事务。
拦截器通过检查方法返回类型来检测所需的事务管理风格。返回响应式类型(如Publisher或Kotlin Flow(或这些类型的子类型)的方法符合响应式事务管理。所有其他返回类型(包括void)都使用强制事务管理的代码路径。
Rolling Back a Declarative Transaction
当抛出的异常是RuntimeException的实例或子类时。(默认情况下,error实例也会导致回滚)。从事务方法抛出的检查异常不会导致默认配置中的回滚。
Using @Transactional
对于声明性事务,事务名称总是完全限定类名+事务通知类的方法名例如,如果BusinessService类的handlePayment(..)方法启动了一个事务,则事务的名称将为
com.example.BusinessService.handlePayment
注意事项:事务有可能失效的场景
应该只对具public的方法应用@Transactional注释。如果使用@Transactional注释protected
,private
, or package-visible的方法,不会引发错误,但注释的方法不会显示配置的事务设置。可以通过下面这样设置对非pubilc的方法设置事务。
/** * Register a custom AnnotationTransactionAttributeSource with the * publicMethodsOnly flag set to false to enable support for * protected and package-private @Transactional methods in * class-based proxies. * * @see ProxyTransactionManagementConfiguration#transactionAttributeSource() */ @Bean TransactionAttributeSource transactionAttributeSource() { return new AnnotationTransactionAttributeSource(false); }
- 在代理模式(这是默认的)中,只有通过代理进入的外部方法调用被拦截。这意味着自调用(实际上,目标对象中的一个方法调用目标对象的另一个方法)不会在运行时导致实际事务,即使被调用的方法被标记为@Transactional。
- @EnableTransactionManagement和<tx:注释驱动/>只在定义它们的同一个应用程序上下文中的bean上寻找@Transactional。这意味着,如果您将注释驱动的配置放在一个DispatcherServlet的WebApplicationContext中,它只会在controllers中检查@Transactional bean,而不是在services中
@Transactional
Settings
默认@Transactional设置如下:
propagation设置为PROPAGATION_REQUIRED。
isolation级别为ISOLATION_DEFAULT。
事务是读写的。
事务超时默认为基础事务系统的默认超时,如果不支持超时,则为none。
任何RuntimeException都会触发回滚,而任何checked
Exception
不会
DAO Support
Spring中的数据访问对象(DAO)支持旨在以一致的方式简化数据访问技术(如JDBC、Hibernate或JPA)。这使您可以非常容易地在上述持久性技术之间进行切换,而且还使您不必担心捕获特定于每种技术的异常。
确保数据访问对象(dao)或repositories提供异常转换的最佳方法是使用@Repository注释。该注释还允许组件扫描支持查找和配置dao和repositories
Data Access with JDBC
Spring框架的JDBC抽象框架由四个不同的包组成
- core: org.springframework.jdbc.core包包含了JdbcTemplate类和它的各种回调接口,以及各种相关类
- datasource: org.springframework.jdbc.datasource包包含了一个实用程序类
- 数据源访问和各种可以用于测试的简单数据源实现以及在Java EE容器外运行未修改的JDBC代码
- object: org.springframework.jdbc.object包包含代表RDBMS的类查询、更新和存储过程作为线程安全的、可重用的对象
- support: org.springframework.jdbc.support包提供了SQLException转换功能和一些实用程序类
Using JdbcTemplate
JdbcTemplate类:实例是线程安全的
•运行SQL查询
•更新语句和存储过程调用
•对ResultSet实例进行迭代,并提取返回的参数值。
•捕获JDBC异常并将其转换为通用的、信息更丰富的异常private final RowMapper<Actor> actorRowMapper = (resultSet, rowNum) -> { Actor actor = new Actor(); actor.setFirstName(resultSet.getString("first_name")); actor.setLastName(resultSet.getString("last_name")); return actor; }; public List<Actor> findAllActors() { return this.jdbcTemplate.query( "select first_name, last_name from t_actor", actorRowMapper); }
JDBC Batch Operations
- JdbcTemplate
public class JdbcActorDao implements ActorDao {
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public int[] batchUpdate(final List<Actor> actors) {
return this.jdbcTemplate.batchUpdate(
"update t_actor set first_name = ?, last_name = ? where id = ?",
new BatchPreparedStatementSetter() {
public void setValues(PreparedStatement ps, int i) throws
SQLException {
Actor actor = actors.get(i);
ps.setString(1, actor.getFirstName());
ps.setString(2, actor.getLastName());
ps.setLong(3, actor.getId().longValue());
}
public int getBatchSize() {
return actors.size();
}
});
}
// ... additional methods
}
- Batch Operations with Multiple Batches 多批次批处理
public class JdbcActorDao implements ActorDao {
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public int[][] batchUpdate(final Collection<Actor> actors) {
int[][] updateCounts = jdbcTemplate.batchUpdate(
"update t_actor set first_name = ?, last_name = ? where id = ?",
actors,
100,
(PreparedStatement ps, Actor actor) -> {
ps.setString(1, actor.getFirstName());
ps.setString(2, actor.getLastName());
ps.setLong(3, actor.getId().longValue());
});
return updateCounts;
}
// ... additional methods
}
此调用的批处理更新方法返回一个数组
int
数组,其中包含每个批处理的数组条目,以及每个更新受影响的行数的数组。顶级数组的长度表示运行的批次数,第二级数组的长度表示该批次中的更新次数。每个批次中的更新数量应该是为所有批次提供的批次大小(除了最后一个可能更少),具体取决于提供的更新对象的总数。每个更新语句的更新计数是 JDBC 驱动程序报告的计数。如果计数不可用,则 JDBC 驱动程序返回值-2
Simplifying JDBC Operations with the SimpleJdbc Classes
https://docs.spring.io/spring-framework/docs/5.3.9/reference/html/data-access.html#jdbc-simple-jdbc
提供了一个简化的配置可以通过JDBC驱动程序检索数据库元数据的优点
参数和数据值处理的常见问题
响应式关系数据库处理R2DBC
Reactive Relational Database Connectivity。R2DBC是基于Reactive Streams标准来设计的。通过使用R2DBC,你可以使用reactive API来操作数据。
Object Relational Mapping (ORM) Data Access
Hibernate
从 Spring Framework 5.3 开始,Spring 需要 Hibernate ORM 5.2+ 才能用于 Spring
- SessionFactory Setup in a Spring Container
- Three Options for JPA Setup in a Spring Environment
Marshalling XML by Using ObjectXML Mappers
Object-XML映射(O-X映射是在XML文档和对象之间进行转换的行为。这个转换过程也称为XML编组或XML序列化)。
- Ease of configuration
Spring 的 bean factory 可以轻松配置 marshallers
- Consistent Interfaces
Spring 的 OX 映射通过两个全局接口运行:
Marshaller
和Unmarshaller
- Consistent Exception Hierarchy
Spring 提供了从底层 OX 映射工具的异常到它自己的异常层次结构的转换,以
XmlMappingException
为根 异常
Marshaller
将object序列化为 XML,Unmarshaller
将 XML 流反序列化为object