- 浏览: 565097 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (267)
- 随笔 (4)
- Spring (13)
- Java (61)
- HTTP (3)
- Windows (1)
- CI(Continuous Integration) (3)
- Dozer (1)
- Apache (11)
- DB (7)
- Architecture (41)
- Design Patterns (11)
- Test (5)
- Agile (1)
- ORM (3)
- PMP (2)
- ESB (2)
- Maven (5)
- IDE (1)
- Camel (1)
- Webservice (3)
- MySQL (6)
- CentOS (14)
- Linux (19)
- BI (3)
- RPC (2)
- Cluster (9)
- NoSQL (7)
- Oracle (25)
- Loadbalance (7)
- Web (5)
- tomcat (1)
- freemarker (1)
- 制造 (0)
最新评论
-
panamera:
如果设置了连接需要密码,Dynamic Broker-Clus ...
ActiveMQ 集群配置 -
panamera:
请问你的最后一种模式Broker-C节点是不是应该也要修改持久 ...
ActiveMQ 集群配置 -
maosheng:
longshao_feng 写道楼主使用 文件共享 模式的ma ...
ActiveMQ 集群配置 -
longshao_feng:
楼主使用 文件共享 模式的master-slave,produ ...
ActiveMQ 集群配置 -
tanglanwen:
感触很深,必定谨记!
少走弯路的十条忠告
在Spring中,JdbcTemplate是经常被使用的类来帮助用户程序操作数据库,在JdbcTemplate为用户程序提供了许多便利的数据库操作方法,比如查询,更新等,而且在Spring中,有许多类似JdbcTemplate的模板,比如HibernateTemplate等等。
一般而言这种Template中都是通过回调函数CallBack类的使用来完成功能的,客户需要在回调接口中实现自己需要的定制行为,比如使用客户想要用的SQL语句等。不过往往Spring通过这种回调函数的实现已经为我们提供了许多现成的方法供客户使用。
一般来说回调函数的用法采用匿名类的方式来实现,比如:
JdbcTemplate = new JdbcTemplate(datasource);
jdbcTemplate.execute(new CallBack(){
public CallbackInterfacedoInAction(){
//用户定义的代码或者说Spring替我们实现的代码
.......
}
}
在模板中嵌入的是需要客户化的代码,由Spring来作或者需要客户程序亲自动手完成。下面让我们具体看看在JdbcTemplate中的代码是怎样完成使命的,我们举JdbcTemplate.execute()为例,这个方法是在JdbcTemplate中被其他方法调用的基本方法之一,客户程序往往用这个方法来执行基本的SQL语句:
Java代码
public <T> T execute(ConnectionCallback<T> action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
//这里得到数据库联接
Connection con = DataSourceUtils.getConnection(getDataSource());
try {
Connection conToUse = con;
if (this.nativeJdbcExtractor != null) {
// Extract native JDBC Connection, castable to OracleConnection or the like.
conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
}
else {
// Create close-suppressing Connection proxy, also preparing returned Statements.
conToUse = createConnectionProxy(con);
}
//这里调用的是传递进来的匿名类的方法,也就是用户程序需要实现CallBack接口的地方
return action.doInConnection(conToUse);
}
catch (SQLException ex) {
// Release Connection early, to avoid potential connection pool deadlock
// in the case when the exception translator hasn't been initialized yet.
//如果捕捉到数据库异常,把数据库联接释放,同时抛出一个经过Spring转换过的Spring数据库异常
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("ConnectionCallback", getSql(action), ex);
}
finally {
//最后不管怎样都会把数据库连接释放
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
/**
* Generic callback interface for code that operates on a JDBC Connection.
* Allows to execute any number of operations on a single Connection,
* using any type and number of Statements.
*
* <p>This is particularly useful for delegating to existing data access code
* that expects a Connection to work on and throws SQLException. For newly
* written code, it is strongly recommended to use JdbcTemplate's more specific
* operations, for example a <code>query</code> or <code>update</code> variant.
*
* @author Juergen Hoeller
* @since 1.1.3
* @see JdbcTemplate#execute(ConnectionCallback)
* @see JdbcTemplate#query
* @see JdbcTemplate#update
*/
public interface ConnectionCallback<T> {
/**
* Gets called by <code>JdbcTemplate.execute</code> with an active JDBC
* Connection. Does not need to care about activating or closing the
* Connection, or handling transactions.
*
* <p>If called without a thread-bound JDBC transaction (initiated by
* DataSourceTransactionManager), the code will simply get executed on the
* JDBC connection with its transactional semantics. If JdbcTemplate is
* configured to use a JTA-aware DataSource, the JDBC Connection and thus
* the callback code will be transactional if a JTA transaction is active.
*
* <p>Allows for returning a result object created within the callback, i.e.
* a domain object or a collection of domain objects. Note that there's special
* support for single step actions: see <code>JdbcTemplate.queryForObject</code>
* etc. A thrown RuntimeException is treated as application exception:
* it gets propagated to the caller of the template.
*
* @param con active JDBC Connection
* @return a result object, or <code>null</code> if none
* @throws SQLException if thrown by a JDBC method, to be auto-converted
* to a DataAccessException by a SQLExceptionTranslator
* @throws DataAccessException in case of custom exceptions
* @see JdbcTemplate#queryForObject(String, Class)
* @see JdbcTemplate#queryForRowSet(String)
*/
T doInConnection(Connection con) throws SQLException, DataAccessException;
}
对于JdbcTemplate中给出的其他方法,比如query,update,execute等的实现,我们看看query():
/**
* Query using a prepared statement, allowing for a PreparedStatementCreator
* and a PreparedStatementSetter. Most other query methods use this method,
* but application code will always work with either a creator or a setter.
* @param psc Callback handler that can create a PreparedStatement given a
* Connection
* @param pss object that knows how to set values on the prepared statement.
* If this is null, the SQL will be assumed to contain no bind parameters.
* @param rse object that will extract results.
* @return an arbitrary result object, as returned by the ResultSetExtractor
* @throws DataAccessException if there is any problem
*/
public <T> T query(
PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor<T> rse)
throws DataAccessException {
Assert.notNull(rse, "ResultSetExtractor must not be null");
logger.debug("Executing prepared SQL query");
//这里调用了我们上面看到的execute()基本方法,然而这里的回调实现是Spring为我们完成的查询过程
return execute(psc, new PreparedStatementCallback<T>() {
public T doInPreparedStatement(PreparedStatement ps) throws SQLException {
//准备查询结果集
ResultSet rs = null;
try {
//这里配置SQL参数
if (pss != null) {
pss.setValues(ps);
}
//这里执行的SQL查询
rs = ps.executeQuery();
ResultSet rsToUse = rs;
if (nativeJdbcExtractor != null) {
rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
}
//返回需要的记录集合
return rse.extractData(rsToUse);
}
finally {
JdbcUtils.closeResultSet(rs);
if (pss instanceof ParameterDisposer) {
((ParameterDisposer) pss).cleanupParameters();
}
}
}
});
}
辅助类DataSourceUtils来用来对数据库连接进行管理的主要工具,比如打开和关闭数据库连接等基本操作:
/**
* Obtain a Connection from the given DataSource. Translates SQLExceptions into
* the Spring hierarchy of unchecked generic data access exceptions, simplifying
* calling code and making any exception that is thrown more meaningful.
* <p>Is aware of a corresponding Connection bound to the current thread, for example
* when using {@link DataSourceTransactionManager}. Will bind a Connection to the
* thread if transaction synchronization is active, e.g. when running within a
* {@link org.springframework.transaction.jta.JtaTransactionManager JTA} transaction).
* @param dataSource the DataSource to obtain Connections from
* @return a JDBC Connection from the given DataSource
* @throws org.springframework.jdbc.CannotGetJdbcConnectionException
* if the attempt to get a Connection failed
* @see #releaseConnection
*/
public static Connection getConnection(DataSource dataSource) throws CannotGetJdbcConnectionException {
try {
return doGetConnection(dataSource);
}
catch (SQLException ex) {
throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex);
}
}
/**
* Actually obtain a JDBC Connection from the given DataSource.
* Same as {@link #getConnection}, but throwing the original SQLException.
* <p>Is aware of a corresponding Connection bound to the current thread, for example
* when using {@link DataSourceTransactionManager}. Will bind a Connection to the thread
* if transaction synchronization is active (e.g. if in a JTA transaction).
* <p>Directly accessed by {@link TransactionAwareDataSourceProxy}.
* @param dataSource the DataSource to obtain Connections from
* @return a JDBC Connection from the given DataSource
* @throws SQLException if thrown by JDBC methods
* @see #doReleaseConnection
*/
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(dataSource.getConnection());
}
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 = dataSource.getConnection();
if (TransactionSynchronizationManager.isSynchronizationActive()) {
logger.debug("Registering transaction synchronization for JDBC Connection");
// 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);
}
}
return con;
}
那我们实际的DataSource对象是怎样得到的?很清楚我们需要在上下文中进行配置:它作为
JdbcTemplate父类JdbcAccessor的属性存在:
/**
* Base class for {@link org.springframework.jdbc.core.JdbcTemplate} and
* other JDBC-accessing DAO helpers, defining common properties such as
* DataSource and exception translator.
*
* <p>Not intended to be used directly.
* See {@link org.springframework.jdbc.core.JdbcTemplate}.
*
* @author Juergen Hoeller
* @since 28.11.2003
* @see org.springframework.jdbc.core.JdbcTemplate
*/
public abstract class JdbcAccessor implements InitializingBean {
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
private DataSource dataSource;
private SQLExceptionTranslator exceptionTranslator;
private boolean lazyInit = true;
/**
* Set the JDBC DataSource to obtain connections from.
*/
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* Return the DataSource used by this template.
*/
public DataSource getDataSource() {
return this.dataSource;
}
.......
}
一般而言这种Template中都是通过回调函数CallBack类的使用来完成功能的,客户需要在回调接口中实现自己需要的定制行为,比如使用客户想要用的SQL语句等。不过往往Spring通过这种回调函数的实现已经为我们提供了许多现成的方法供客户使用。
一般来说回调函数的用法采用匿名类的方式来实现,比如:
JdbcTemplate = new JdbcTemplate(datasource);
jdbcTemplate.execute(new CallBack(){
public CallbackInterfacedoInAction(){
//用户定义的代码或者说Spring替我们实现的代码
.......
}
}
在模板中嵌入的是需要客户化的代码,由Spring来作或者需要客户程序亲自动手完成。下面让我们具体看看在JdbcTemplate中的代码是怎样完成使命的,我们举JdbcTemplate.execute()为例,这个方法是在JdbcTemplate中被其他方法调用的基本方法之一,客户程序往往用这个方法来执行基本的SQL语句:
Java代码
public <T> T execute(ConnectionCallback<T> action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
//这里得到数据库联接
Connection con = DataSourceUtils.getConnection(getDataSource());
try {
Connection conToUse = con;
if (this.nativeJdbcExtractor != null) {
// Extract native JDBC Connection, castable to OracleConnection or the like.
conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
}
else {
// Create close-suppressing Connection proxy, also preparing returned Statements.
conToUse = createConnectionProxy(con);
}
//这里调用的是传递进来的匿名类的方法,也就是用户程序需要实现CallBack接口的地方
return action.doInConnection(conToUse);
}
catch (SQLException ex) {
// Release Connection early, to avoid potential connection pool deadlock
// in the case when the exception translator hasn't been initialized yet.
//如果捕捉到数据库异常,把数据库联接释放,同时抛出一个经过Spring转换过的Spring数据库异常
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("ConnectionCallback", getSql(action), ex);
}
finally {
//最后不管怎样都会把数据库连接释放
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
/**
* Generic callback interface for code that operates on a JDBC Connection.
* Allows to execute any number of operations on a single Connection,
* using any type and number of Statements.
*
* <p>This is particularly useful for delegating to existing data access code
* that expects a Connection to work on and throws SQLException. For newly
* written code, it is strongly recommended to use JdbcTemplate's more specific
* operations, for example a <code>query</code> or <code>update</code> variant.
*
* @author Juergen Hoeller
* @since 1.1.3
* @see JdbcTemplate#execute(ConnectionCallback)
* @see JdbcTemplate#query
* @see JdbcTemplate#update
*/
public interface ConnectionCallback<T> {
/**
* Gets called by <code>JdbcTemplate.execute</code> with an active JDBC
* Connection. Does not need to care about activating or closing the
* Connection, or handling transactions.
*
* <p>If called without a thread-bound JDBC transaction (initiated by
* DataSourceTransactionManager), the code will simply get executed on the
* JDBC connection with its transactional semantics. If JdbcTemplate is
* configured to use a JTA-aware DataSource, the JDBC Connection and thus
* the callback code will be transactional if a JTA transaction is active.
*
* <p>Allows for returning a result object created within the callback, i.e.
* a domain object or a collection of domain objects. Note that there's special
* support for single step actions: see <code>JdbcTemplate.queryForObject</code>
* etc. A thrown RuntimeException is treated as application exception:
* it gets propagated to the caller of the template.
*
* @param con active JDBC Connection
* @return a result object, or <code>null</code> if none
* @throws SQLException if thrown by a JDBC method, to be auto-converted
* to a DataAccessException by a SQLExceptionTranslator
* @throws DataAccessException in case of custom exceptions
* @see JdbcTemplate#queryForObject(String, Class)
* @see JdbcTemplate#queryForRowSet(String)
*/
T doInConnection(Connection con) throws SQLException, DataAccessException;
}
对于JdbcTemplate中给出的其他方法,比如query,update,execute等的实现,我们看看query():
/**
* Query using a prepared statement, allowing for a PreparedStatementCreator
* and a PreparedStatementSetter. Most other query methods use this method,
* but application code will always work with either a creator or a setter.
* @param psc Callback handler that can create a PreparedStatement given a
* Connection
* @param pss object that knows how to set values on the prepared statement.
* If this is null, the SQL will be assumed to contain no bind parameters.
* @param rse object that will extract results.
* @return an arbitrary result object, as returned by the ResultSetExtractor
* @throws DataAccessException if there is any problem
*/
public <T> T query(
PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor<T> rse)
throws DataAccessException {
Assert.notNull(rse, "ResultSetExtractor must not be null");
logger.debug("Executing prepared SQL query");
//这里调用了我们上面看到的execute()基本方法,然而这里的回调实现是Spring为我们完成的查询过程
return execute(psc, new PreparedStatementCallback<T>() {
public T doInPreparedStatement(PreparedStatement ps) throws SQLException {
//准备查询结果集
ResultSet rs = null;
try {
//这里配置SQL参数
if (pss != null) {
pss.setValues(ps);
}
//这里执行的SQL查询
rs = ps.executeQuery();
ResultSet rsToUse = rs;
if (nativeJdbcExtractor != null) {
rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
}
//返回需要的记录集合
return rse.extractData(rsToUse);
}
finally {
JdbcUtils.closeResultSet(rs);
if (pss instanceof ParameterDisposer) {
((ParameterDisposer) pss).cleanupParameters();
}
}
}
});
}
辅助类DataSourceUtils来用来对数据库连接进行管理的主要工具,比如打开和关闭数据库连接等基本操作:
/**
* Obtain a Connection from the given DataSource. Translates SQLExceptions into
* the Spring hierarchy of unchecked generic data access exceptions, simplifying
* calling code and making any exception that is thrown more meaningful.
* <p>Is aware of a corresponding Connection bound to the current thread, for example
* when using {@link DataSourceTransactionManager}. Will bind a Connection to the
* thread if transaction synchronization is active, e.g. when running within a
* {@link org.springframework.transaction.jta.JtaTransactionManager JTA} transaction).
* @param dataSource the DataSource to obtain Connections from
* @return a JDBC Connection from the given DataSource
* @throws org.springframework.jdbc.CannotGetJdbcConnectionException
* if the attempt to get a Connection failed
* @see #releaseConnection
*/
public static Connection getConnection(DataSource dataSource) throws CannotGetJdbcConnectionException {
try {
return doGetConnection(dataSource);
}
catch (SQLException ex) {
throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex);
}
}
/**
* Actually obtain a JDBC Connection from the given DataSource.
* Same as {@link #getConnection}, but throwing the original SQLException.
* <p>Is aware of a corresponding Connection bound to the current thread, for example
* when using {@link DataSourceTransactionManager}. Will bind a Connection to the thread
* if transaction synchronization is active (e.g. if in a JTA transaction).
* <p>Directly accessed by {@link TransactionAwareDataSourceProxy}.
* @param dataSource the DataSource to obtain Connections from
* @return a JDBC Connection from the given DataSource
* @throws SQLException if thrown by JDBC methods
* @see #doReleaseConnection
*/
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(dataSource.getConnection());
}
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 = dataSource.getConnection();
if (TransactionSynchronizationManager.isSynchronizationActive()) {
logger.debug("Registering transaction synchronization for JDBC Connection");
// 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);
}
}
return con;
}
那我们实际的DataSource对象是怎样得到的?很清楚我们需要在上下文中进行配置:它作为
JdbcTemplate父类JdbcAccessor的属性存在:
/**
* Base class for {@link org.springframework.jdbc.core.JdbcTemplate} and
* other JDBC-accessing DAO helpers, defining common properties such as
* DataSource and exception translator.
*
* <p>Not intended to be used directly.
* See {@link org.springframework.jdbc.core.JdbcTemplate}.
*
* @author Juergen Hoeller
* @since 28.11.2003
* @see org.springframework.jdbc.core.JdbcTemplate
*/
public abstract class JdbcAccessor implements InitializingBean {
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
private DataSource dataSource;
private SQLExceptionTranslator exceptionTranslator;
private boolean lazyInit = true;
/**
* Set the JDBC DataSource to obtain connections from.
*/
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* Return the DataSource used by this template.
*/
public DataSource getDataSource() {
return this.dataSource;
}
.......
}
发表评论
-
Spring Cloud 微服务异常处理机制
2020-04-27 15:43 0在基于SpringCloud的微服务架构中,所有服务都是通过如 ... -
SpringCloud Ribbon的重试和Hystrix的超时时间配置
2020-04-27 15:27 939先看下Ribbon的配置和Hystrix的超时配置: ribb ... -
SpringCloud Hystrix实现服务熔断和服务降级
2020-02-17 15:06 673一.雪崩效应 (1)微服 ... -
Spring MVC 基于 RequestBodyAdvice 和 ResponseBodyAdvice 全局处理输入输出
2020-02-14 13:46 1670使用场景: 1.需要对项目中的所有输入进行前后空格的过滤 2 ... -
Spring Boot集成dubbo,mybatis构建maven工程
2017-07-14 10:54 1188一.Dubbo服务提供者(Spring Boot+Dubbo+ ... -
深入学习微框架:Spring Boot
2016-01-19 16:52 1630Spring Boot是由Pivotal团队 ... -
使用Spring Boot 创建微服务
2016-01-19 16:48 1051过去几年以来,“微服 ... -
基于CGLib(面向Class)的Spring AOP实现原理
2013-07-17 16:47 1476Spring中,基于Dynamic Proxy是面向接口的动态 ... -
基于Java Dynamic Proxy(面向Interface)的Spring AOP实现原理
2013-07-17 16:23 1519Dynamic Proxy是面向接口的动态代理实现,其代理对象 ... -
Spring 基于注解驱动的MVC
2012-03-16 17:18 1292继 Spring 2.0 对 Spring MVC 进行重大升 ... -
Hard code获取Spring中Bean的几种方法
2012-01-05 14:01 1397方法一:(通过FileSystemXmlApplication ... -
配置文件加载Spring配置文件方法
2012-01-05 13:39 1112方法一:(web.xml)<web-app> ... -
反射实现AOP 动态代理模式(Spring AOP 的实现原理)
2011-12-22 17:24 1170我们先写一个接口IHello.java代码如下: 1 pa ...
相关推荐
本篇将深入探讨Spring JDBCTemplate的使用及其源码解析,帮助你理解其背后的机制。 首先,让我们了解在不使用JDBCTemplate时,传统的JDBC操作通常涉及以下步骤:加载驱动、建立数据库连接、创建Statement或...
源码深度解析对于开发者来说,是理解Spring工作原理、提升技术水平的重要途径。本资源提供了完整的Spring源码,附带注释和实例,对初学者极其友好。 首先,我们来探讨Spring的核心模块: 1. **IoC容器**:Spring的...
Spring提供了JdbcTemplate和JPA(Java Persistence API)等工具,简化了数据库操作。Repository接口可以定义数据访问的方法,通过实现这些接口,我们可以定义特定的数据库查询逻辑。 在Spring源码中,可以看到以下...
在IoC(Inversion of Control,控制反转)容器方面,Spring 3.2提高了配置文件的解析效率,增强了XML和Java配置的互操作性。它还引入了Profile功能,可以根据不同的运行环境加载不同的配置,增加了应用的可部署性。 ...
在源码中,你可以看到Repository接口的抽象,以及JdbcTemplate和JPA的实现细节,这有助于理解数据访问的底层逻辑。 Spring还提供了对事务管理的支持,包括编程式和声明式事务。在源码中,你可以看到...
本文将通过对Spring源码的深入解析,逐一探讨这些核心组件的工作原理。 首先,我们关注Spring的事务处理。在Spring中,事务管理是通过声明式和编程式两种方式实现的。声明式事务管理基于XML配置或注解,使得开发者...
3. **Spring JDBC**:Spring提供了JdbcTemplate和JpaTemplate等工具类,简化了数据库访问。它们封装了SQL执行和结果集处理,减少了重复代码,提高了可测试性。同时,Spring的数据源管理、事务管理与JDBC紧密结合,...
本文将深入解析Spring的源代码,帮助开发者理解其内部机制,提升对框架的使用技巧和定制能力。 首先,Spring的核心模块包括IoC(Inversion of Control,控制反转)容器、AOP、数据访问/集成、Web模块等。IoC容器是...
--多种数据源的配置、JdbcTemplate、事务的处理 20 Spring Boot AOP 21 Spring Boot Starter18:31 --快速构建自定义的Spring Boot Starter 22 Spring Boot 日志30:58 --演示了如何在Spring Boot里面使用日志配置...
本篇文章将深入解析Spring JDBC的实现,特别是JdbcTemplate类。JdbcTemplate是Spring为简化数据库操作而设计的一个模板类,它封装了数据库连接获取、SQL执行、异常处理等细节,使开发者可以更专注于业务逻辑。 ...
7. **Web MVC**:Spring MVC是Spring框架的重要组成部分,3.1版本中增加了对RESTful风格的支持,增强了ModelAndView对象,以及改进了视图解析器。 8. **缓存抽象**:Spring 3.1引入了统一的缓存抽象,支持EhCache、...
以下是对Spring源码解析的详细知识点: 1. **依赖注入(DI, Dependency Injection)**:Spring通过DI机制管理对象的生命周期和依赖关系,使得组件之间解耦。源码中,`ApplicationContext`是DI的主要实现,通过`...
同时,Spring的DAO支持类如JdbcTemplate和HibernateTemplate提供了更方便的数据库操作接口。 五、RESTful支持 Spring 3.0引入了对RESTful风格API的支持,可以通过`@ResponseBody`和`@RequestBody`注解进行HTTP请求...
Spring的JdbcTemplate和JPA提供了一致的编程模型,简化数据库操作。 7. **Spring MVC**:Spring的Model-View-Controller架构用于构建Web应用程序。DispatcherServlet作为前端控制器,接收请求并分发到相应的处理器...
- **MVC**:Spring MVC在4.0中得到了显著增强,例如支持RESTful风格的URL路由,改进了视图解析,以及支持HTTP/2和WebSocket。 - **JSON支持**:对Jackson库的集成加强,支持更方便的JSON序列化和反序列化。 - **...
本资料“Spring学习笔记&源码”是基于网易云课堂黑马程序员的Spring四天精通课程,旨在帮助学习者深入理解和实践Spring框架。 笔记部分可能会涵盖以下内容: 1. **Spring概述**:介绍Spring框架的历史、特点和主要...
- **数据访问**:深入 Hibernate 和 JdbcTemplate 模块,理解 Spring 如何与 ORM 工具集成,提供数据访问抽象。 - **模块化设计**:Spring 框架由多个模块组成,如 Core Container、Data Access/Integration、Web、...
在源码中,我们可以看到`BeanFactory`和`ApplicationContext`接口如何实现对bean的生命周期管理和依赖解析。 2. **AOP(面向切面编程)**: Spring 3.2.0加强了AOP支持,允许开发者定义和执行横切关注点,如日志...