测试代码:
@Service
public class StockServiceImpl implements StockService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public String getStockName() {
String s = jdbcTemplate.queryForObject("select `name` from stock where id = 1;", String.class);
return s;
}
}
在创建bean时,spring通过jdk动态代理为StockService创建动态代理类,上图为运行时调用过程
运行时从JdkDynamicAopProxy的invoke方法开始,然后调用AopUtils的invokeJoinpointUsingReflection方法,
再通过method.invoke(target, args) 调用到StockServiceImpl的getStockName方法,开始执行jdbcTemplate.queryForObject
然后调用jdbcTemplate的execute方法,此时先通过JdbcAccessor类的obtainDataSource()方法获取数据源,默认为HikariDataSource数据源,然后通过DataSourceUtils.getConnection(obtainDataSource()) 获取连接,下面的过程就是jdbc的执行过程。返回结果之前 先关闭statement和释放连接(数据源层面来看归还连接)
其中DataSourceUtils.getConnection(obtainDataSource()) 获取连接的过程中,还会如下代码:
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();
}
如果conHolder 中不为空的话,那么会直接返回连接,什么时候不为空呢?
首先通过TransactionSynchronizationManager获得ConnectionHolder,
如果当前线程有绑定的事务,那么spring为了保证同一个事务中使用同一个连接,会将连接绑定到线程,那么此处conHolder就不为空了
网友评论