From fc23bc36b8b0cd5f231e3c5e2b997e94dd97ddbd Mon Sep 17 00:00:00 2001 From: yanglbme Date: Tue, 15 Apr 2025 06:31:22 +0800 Subject: [PATCH] fix: update docs --- docs/Spring/JDBC/Spring-jdbc.md | 483 ------------------ .../Spring事务处理的设计与实现.md | 2 +- .../Spring-PlaceholderResolver.md | 2 +- docs/Spring/clazz/Spring-BeanNameGenerator.md | 2 +- docs/Spring/clazz/Spring-Property.md | 6 +- 5 files changed, 6 insertions(+), 489 deletions(-) diff --git a/docs/Spring/JDBC/Spring-jdbc.md b/docs/Spring/JDBC/Spring-jdbc.md index bdc8189..e69de29 100644 --- a/docs/Spring/JDBC/Spring-jdbc.md +++ b/docs/Spring/JDBC/Spring-jdbc.md @@ -1,483 +0,0 @@ -# Spring JDBC - -- Author: [HuiFer](https://github.com/huifer) -- 源码阅读仓库: [SourceHot-Spring](https://github.com/SourceHot/spring-framework-read) - -## 环境搭建 - -- 依赖 - - ```gradle - compile(project(":spring-jdbc")) - compile group: 'com.alibaba', name: 'druid', version: '1.1.21' - compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.47' - ``` - -- db 配置 - - ```properties - jdbc.url= - jdbc.driverClass= - jdbc.username= - jdbc.password= - ``` - -- 实体对象 - - ```java - public class HsLog { - private Integer id; - - private String source; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getSource() { - return source; - } - - public void setSource(String source) { - this.source = source; - } - } - ``` - -- DAO - - ```java - public interface HsLogDao { - List findAll(); - - void save(HsLog hsLog); - } - - ``` - -- 实现类 - - ```java - public class HsLogDaoImpl extends JdbcDaoSupport implements HsLogDao { - - - @Override - public List findAll() { - return this.getJdbcTemplate().query("select * from hs_log", new HsLogRowMapper()); - - } - - @Override - public void save(HsLog hsLog) { - this.getJdbcTemplate().update("insert into hs_log (SOURCE) values(?)" - , new Object[]{ - hsLog.getSource(), - } - - ); - } - - class HsLogRowMapper implements RowMapper { - - public HsLog mapRow(ResultSet rs, int rowNum) throws SQLException { - - HsLog log = new HsLog(); - log.setId(rs.getInt("id")); - log.setSource(rs.getString("source")); - return log; - } - - } - } - - ``` - -- xml - - ```xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ``` - -- 运行方法 - - ```java - - public class SpringJDBCSourceCode { - public static void main(String[] args) { - ApplicationContext applicationContext = new ClassPathXmlApplicationContext("JDBC-demo.xml"); - HsLogDaoImpl bean = applicationContext.getBean(HsLogDaoImpl.class); - System.out.println(bean.findAll()); - HsLog hsLog = new HsLog(); - hsLog.setSource("jlkjll"); - bean.save(hsLog); - - } - } - - ``` - -## 链接对象构造 - -`Connection con = DataSourceUtils.getConnection(obtainDataSource());` - -```java - public static Connection getConnection(DataSource dataSource) throws CannotGetJdbcConnectionException { - try { - return doGetConnection(dataSource); - } - catch (SQLException ex) { - throw new CannotGetJdbcConnectionException("Failed to obtain JDBC Connection", ex); - } - catch (IllegalStateException ex) { - throw new CannotGetJdbcConnectionException("Failed to obtain JDBC Connection: " + ex.getMessage()); - } - } - -``` - -### org.springframework.jdbc.datasource.DataSourceUtils#doGetConnection - -```java - public static Connection doGetConnection(DataSource dataSource) throws SQLException { - Assert.notNull(dataSource, "No DataSource specified"); - - ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); - if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) { - conHolder.requested(); - if (!conHolder.hasConnection()) { - logger.debug("Fetching resumed JDBC Connection from DataSource"); - // 设置连接对象 - conHolder.setConnection(fetchConnection(dataSource)); - } - return conHolder.getConnection(); - } - // Else we either got no holder or an empty thread-bound holder here. - - logger.debug("Fetching JDBC Connection from DataSource"); - // 获取链接 - Connection con = fetchConnection(dataSource); - - // 当前线程支持同步 - if (TransactionSynchronizationManager.isSynchronizationActive()) { - try { - // Use same Connection for further JDBC actions within the transaction. - // Thread-bound object will get removed by synchronization at transaction completion. - // 在同一个事物中使用同一个链接对象 - ConnectionHolder holderToUse = conHolder; - if (holderToUse == null) { - holderToUse = new ConnectionHolder(con); - } - else { - holderToUse.setConnection(con); - } - // 记录链接数量 - holderToUse.requested(); - TransactionSynchronizationManager.registerSynchronization( - new ConnectionSynchronization(holderToUse, dataSource)); - holderToUse.setSynchronizedWithTransaction(true); - if (holderToUse != conHolder) { - TransactionSynchronizationManager.bindResource(dataSource, holderToUse); - } - } - catch (RuntimeException ex) { - // Unexpected exception from external delegation call -> close Connection and rethrow. - releaseConnection(con, dataSource); - throw ex; - } - } - - return con; - } - -``` - -## 释放资源 - -`releaseConnection(con, dataSource);` - -- `org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection` - -```java - public static void releaseConnection(@Nullable Connection con, @Nullable DataSource dataSource) { - try { - doReleaseConnection(con, dataSource); - } - catch (SQLException ex) { - logger.debug("Could not close JDBC Connection", ex); - } - catch (Throwable ex) { - logger.debug("Unexpected exception on closing JDBC Connection", ex); - } - } - -``` - -```java -public static void doReleaseConnection(@Nullable Connection con, @Nullable DataSource dataSource) throws SQLException { - if (con == null) { - return; - } - if (dataSource != null) { - ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); - if (conHolder != null && connectionEquals(conHolder, con)) { - // It's the transactional Connection: Don't close it. - // 连接数-1 - conHolder.released(); - return; - } - } - // 处理其他情况 - doCloseConnection(con, dataSource); -} -``` - -- `org.springframework.transaction.support.ResourceHolderSupport` - -```java -/** - * Increase the reference count by one because the holder has been requested - * (i.e. someone requested the resource held by it). - */ -public void requested() { - this.referenceCount++; -} - -/** - * Decrease the reference count by one because the holder has been released - * (i.e. someone released the resource held by it). - */ -public void released() { - this.referenceCount--; -} -``` - -## 查询解析 - -### org.springframework.jdbc.core.JdbcTemplate - -```XML - - - - -``` - -- 从配置中可以知道 JdbcTemplate 需要 dataSource 属性, 就从这里开始讲起 -- `org.springframework.jdbc.support.JdbcAccessor.setDataSource`, 这段代码就只做了赋值操作(依赖注入) - -```java -public void setDataSource(@Nullable DataSource dataSource) { - this.dataSource = dataSource; - } -``` - -- 下面`hsLogDao`也是依赖注入本篇不做详细讲述。 - -### org.springframework.jdbc.core.JdbcTemplate#query(java.lang.String, org.springframework.jdbc.core.RowMapper) - -```java - @Override - public List findAll() { - return this.getJdbcTemplate().query("select * from hs_log", new HsLogRowMapper()); - } - -``` - -```java - @Override - @Nullable - public T query(final String sql, final ResultSetExtractor rse) throws DataAccessException { - Assert.notNull(sql, "SQL must not be null"); - Assert.notNull(rse, "ResultSetExtractor must not be null"); - if (logger.isDebugEnabled()) { - logger.debug("Executing SQL query [" + sql + "]"); - } - - /** - * Callback to execute the query. - */ - class QueryStatementCallback implements StatementCallback, SqlProvider { - @Override - @Nullable - public T doInStatement(Statement stmt) throws SQLException { - ResultSet rs = null; - try { - // 执行sql - rs = stmt.executeQuery(sql); - // 1. org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData - return rse.extractData(rs); - } - finally { - JdbcUtils.closeResultSet(rs); - } - } - - @Override - public String getSql() { - return sql; - } - } - - return execute(new QueryStatementCallback()); - } - -``` - -```java - @Override - @Nullable - public T execute(StatementCallback action) throws DataAccessException { - Assert.notNull(action, "Callback object must not be null"); - - Connection con = DataSourceUtils.getConnection(obtainDataSource()); - Statement stmt = null; - try { - stmt = con.createStatement(); - applyStatementSettings(stmt); - // 执行 - T result = action.doInStatement(stmt); - handleWarnings(stmt); - return result; - } - catch (SQLException ex) { - // Release Connection early, to avoid potential connection pool deadlock - // in the case when the exception translator hasn't been initialized yet. - String sql = getSql(action); - JdbcUtils.closeStatement(stmt); - stmt = null; - DataSourceUtils.releaseConnection(con, getDataSource()); - con = null; - throw translateException("StatementCallback", sql, ex); - } - finally { - JdbcUtils.closeStatement(stmt); - DataSourceUtils.releaseConnection(con, getDataSource()); - } - } -``` - -```java - @Override - public List extractData(ResultSet rs) throws SQLException { - List results = (this.rowsExpected > 0 ? new ArrayList<>(this.rowsExpected) : new ArrayList<>()); - int rowNum = 0; - while (rs.next()) { - // 调用自定义的 rowMapper 进行数据处理 - T t = this.rowMapper.mapRow(rs, rowNum++); - results.add(t); - } - return results; - } - -``` - -![image-20200109150841916](https://fastly.jsdelivr.net/gh/doocs/source-code-hunter@main/images/spring/image-20200109150841916.png) - -这样就可以获取到了 - -方法`result`没有什么操作直接返回即可 - -```java - private static T result(@Nullable T result) { - Assert.state(result != null, "No result"); - return result; - } -``` - -## 插入解析 - -```java -@Override - public void save(HsLog hsLog) { - this.getJdbcTemplate().update("insert into hs_log (SOURCE) values(?)" - , new Object[]{ - hsLog.getSource(), - } - - ); - } -``` - -`org.springframework.jdbc.core.JdbcTemplate#update(org.springframework.jdbc.core.PreparedStatementCreator, org.springframework.jdbc.core.PreparedStatementSetter)` - -```java - protected int update(final PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss) - throws DataAccessException { - - logger.debug("Executing prepared SQL update"); - - return updateCount(execute(psc, ps -> { - try { - if (pss != null) { - // 设置请求参数 - pss.setValues(ps); - } - int rows = ps.executeUpdate(); - if (logger.isTraceEnabled()) { - logger.trace("SQL update affected " + rows + " rows"); - } - return rows; - } - finally { - if (pss instanceof ParameterDisposer) { - ((ParameterDisposer) pss).cleanupParameters(); - } - } - })); - } - -``` diff --git a/docs/Spring/SpringTransaction/Spring事务处理的设计与实现.md b/docs/Spring/SpringTransaction/Spring事务处理的设计与实现.md index 4d1f9ed..e7036fa 100644 --- a/docs/Spring/SpringTransaction/Spring事务处理的设计与实现.md +++ b/docs/Spring/SpringTransaction/Spring事务处理的设计与实现.md @@ -24,7 +24,7 @@ 这个 TransactionAspectSupport 的 createTransactionIfNecessary()方法 作为事务创建的入口,其具体的实现时序如下图所示。在 createTransactionIfNecessary()方法 的调用中,会向 AbstractTransactionManager 执行 getTransaction()方法,这个获取 Transaction 事务对象 的过程,在 AbstractTransactionManager 实现 中需要对事务的情况做出不同的处理,然后,创建一个 TransactionStatus,并把这个 TransactionStatus 设置到对应的 TransactionInfo 中去,同时将 TransactionInfo 和当前的线程绑定,从而完成事务的创建过程。createTransactionIfNeccessary()方法 调用中,可以看到两个重要的数据对象 TransactionStatus 和 TransactionInfo 的创建,这两个对象持有的数据是事务处理器对事务进行处理的主要依据,对这两个对象的使用贯穿着整个事务处理的全过程。 -![avatar]() +![avatar](https://fastly.jsdelivr.net/gh/doocs/source-code-hunter@main/images/springTransaction/调用createTransactionIfNecessary()方法的时序图.png) ```java public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean { diff --git a/docs/Spring/clazz/PlaceholderResolver/Spring-PlaceholderResolver.md b/docs/Spring/clazz/PlaceholderResolver/Spring-PlaceholderResolver.md index a994025..444300f 100644 --- a/docs/Spring/clazz/PlaceholderResolver/Spring-PlaceholderResolver.md +++ b/docs/Spring/clazz/PlaceholderResolver/Spring-PlaceholderResolver.md @@ -24,4 +24,4 @@ - 类图如下 -![PropertyPlaceholderConfigurerResolver](/images/spring/PropertyPlaceholderConfigurerResolver.png) +![PropertyPlaceholderConfigurerResolver](https://fastly.jsdelivr.net/gh/doocs/source-code-hunter@main/images/spring/PropertyPlaceholderConfigurerResolver.png) diff --git a/docs/Spring/clazz/Spring-BeanNameGenerator.md b/docs/Spring/clazz/Spring-BeanNameGenerator.md index 97473ad..90748ce 100644 --- a/docs/Spring/clazz/Spring-BeanNameGenerator.md +++ b/docs/Spring/clazz/Spring-BeanNameGenerator.md @@ -22,7 +22,7 @@ public interface BeanNameGenerator { } ``` -![](/images/spring/BeanNameGenerator.png) +![](https://fastly.jsdelivr.net/gh/doocs/source-code-hunter@main/images/spring/BeanNameGenerator.png) ## DefaultBeanNameGenerator diff --git a/docs/Spring/clazz/Spring-Property.md b/docs/Spring/clazz/Spring-Property.md index a973e18..67896f2 100644 --- a/docs/Spring/clazz/Spring-Property.md +++ b/docs/Spring/clazz/Spring-Property.md @@ -11,7 +11,7 @@ - 类图如下 - ![images](/images/spring/PropertyValues.png) + ![images](https://fastly.jsdelivr.net/gh/doocs/source-code-hunter@main/images/spring/PropertyValues.png) - 在 Spring IoC 中,**非 Web 工程**,使用 xml 或者注解进行配置主要使用到的是 `PropertyValues` ,`PropertyValue` ,`MutablePropertyValues` 三个 @@ -27,7 +27,7 @@ - 类图 - ![](/images/spring/PropertyValue.png) + ![](https://fastly.jsdelivr.net/gh/doocs/source-code-hunter@main/images/spring/PropertyValue.png) - 这个类暂时只关注两个属性 @@ -285,7 +285,7 @@ public interface Mergeable { } ``` -![](/images/spring/Mergeable.png) +![](https://fastly.jsdelivr.net/gh/doocs/source-code-hunter@main/images/spring/Mergeable.png) - 看一下 List 怎么实现`merge`