Spring事物的配置样式如下:
<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true"> <property name="transactionManager" ref="transactionManager"/> <property name="transactionAttributes"> <props> <prop key="insert*">PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> </props> </property> </bean> <bean id="myProxy" parent="baseTransactionProxy"> <property name="target" ref="myTarget"/> </bean>
可以看出TransactionProxyFactoryBean是Spring事物的入口;在TransactionProxyFactoryBean中声明了
private final TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
并将TransactionManager, TransactionAttributes赋值给了transactionInterceptor拦截器。该类继承了AbstractSingletonProxyFactoryBean,而AbstractSingletonProxyFactoryBean又实现了InitializingBean接口;在bean初始化完成后会调用 AbstractSigletonProxyFactoryBean的afterPropertiesSet方法。在该方法中又调用了TransactionInterceptor的createMainInterceptor方法
// Add the main interceptor (typically an Advisor).
proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));
protected Object createMainInterceptor() { this.transactionInterceptor.afterPropertiesSet(); if (this.pointcut != null) { return new DefaultPointcutAdvisor(this.pointcut, this.transactionInterceptor); } else { // Rely on default pointcut. return new TransactionAttributeSourceAdvisor(this.transactionInterceptor); } }
至此就完成了Spring事物通知器的注入。
后续的处理就和普通的AOP一样,我们都知道在Spring AOP中是通过JDK的动态代理和CGLIB实现的
JdkDynamicAopProxy.invoke 方法是AOP方法调用的入口。在该方法中有:
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
如果当前方法需要在事物中运行,在中会调用到TransactionInterceptor.invoke()方法。
public Object invoke(final MethodInvocation invocation) throws Throwable { // Work out the target class: may be {@code null}. // The TransactionAttributeSource should be passed the target class // as well as the method, which may be from an interface. Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); // Adapt to TransactionAspectSupport's invokeWithinTransaction... return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() { public Object proceedWithInvocation() throws Throwable { return invocation.proceed(); } }); }
调用父类中的方法是先了事物处理
protected Object invokeWithinTransaction(Method method, Class targetClass, final InvocationCallback invocation) throws Throwable { // If the transaction attribute is null, the method is non-transactional. final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass); final PlatformTransactionManager tm = determineTransactionManager(txAttr); final String joinpointIdentification = methodIdentification(method, targetClass); if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) { // Standard transaction demarcation with getTransaction and commit/rollback calls. TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); Object retVal = null; try { // This is an around advice: Invoke the next interceptor in the chain. // This will normally result in a target object being invoked. retVal = invocation.proceedWithInvocation(); } catch (Throwable ex) { // target invocation exception completeTransactionAfterThrowing(txInfo, ex); throw ex; } finally { cleanupTransactionInfo(txInfo); } commitTransactionAfterReturning(txInfo); return retVal; } else { // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in. try { Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, new TransactionCallback<Object>() { public Object doInTransaction(TransactionStatus status) { TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status); try { return invocation.proceedWithInvocation(); } catch (Throwable ex) { if (txAttr.rollbackOn(ex)) { // A RuntimeException: will lead to a rollback. if (ex instanceof RuntimeException) { throw (RuntimeException) ex; } else { throw new ThrowableHolderException(ex); } } else { // A normal return value: will lead to a commit. return new ThrowableHolder(ex); } } finally { cleanupTransactionInfo(txInfo); } } }); // Check result: It might indicate a Throwable to rethrow. if (result instanceof ThrowableHolder) { throw ((ThrowableHolder) result).getThrowable(); } else { return result; } } catch (ThrowableHolderException ex) { throw ex.getCause(); } } }
相关推荐
Spring 源代码分析系列涵盖了多个关键模块,包括事务处理、IoC容器、JDBC、MVC、AOP以及与Hibernate和Acegi安全框架的集成。以下是对这些知识点的详细阐述: 1. **Spring 事务处理**:Spring 提供了声明式事务管理...
在源码分析中,我们可以看到当一个方法被@Transactional标记后,Spring会创建一个代理,这个代理在目标方法执行前后插入事务管理逻辑。在方法开始前,如果满足事务启动条件,就会调用`PlatformTransactionManager`的...
spring的核心就是IC依赖注入,那么就要先解析依赖配置,然后再注入。所以spring的功能都会出现两块,一块是解析mxl,一块是构建BeanDefinition。...事务增强器也是这样,先要解析事务的标签,然后才是执行事务。
《Spring5 源码分析(第 2 版)》是某Tom老师精心编写的深度解析文档,旨在帮助读者全面理解Spring5的核心机制和设计理念。Spring作为Java领域最为广泛应用的框架之一,其源码的深入理解对于开发者来说至关重要。这篇...
在整个源代码分析中,我们可以看到 Spring 实现声明式事务管理有三个部分: 1. 对在上下文中配置的属性的处理,这里涉及的类是 TransactionAttributeSourceAdvisor,这是一个通知器,用它来对属性值进行处理,属性...
《Spring5 源码分析(第 2 版)》是针对Spring框架第五个主要版本的深度解析著作,由知名讲师倾心打造,旨在帮助读者深入理解Spring框架的内部工作机制,提升对Java企业级应用开发的专业技能。本书涵盖了Spring框架的...
源码分析中,我们可以看到Spring如何在运行时解析`@Transactional`注解,如何创建和维护事务,以及如何处理异常以决定事务是否需要回滚。例如,当出现未检查异常(继承自`RuntimeException`的异常)时,Spring会默认...
总结来说,"Spring事务传播Demo"是一个用于学习和演示Spring事务管理和传播行为的实例,通过分析和实践这个Demo,开发者可以更好地理解和掌握Spring在处理事务时的复杂情况,提升在实际项目中的应用能力。...
一阶段 1、Spring概述 2、一切从bean开始 3、俯瞰Spring架构设计 4、Spring源码下载 二阶段 1、什么是IOC/DI 2、SpringIOC体系结构 3、源码分析-IOC容器的初始化 ...Spring事务源码解析 需要其他源码请私信我
### Spring源码分析知识点 #### 一、Spring框架概述 Spring框架是一个全面的企业级应用开发框架,它通过一系列模块化的组件来支持不同的应用场景和技术需求。Spring的核心价值在于提供了一种简洁的方式来解决企业...
在本文中,我们将深入探讨Spring声明式事务的工作原理,源码分析,以及如何在实际应用中进行实践。 首先,开启Spring的声明式事务管理需要在配置类上使用`@EnableTransactionManagement`注解。这表示Spring将启用...
以上只是Spring源码分析的部分内容,实际源码中还包括Spring的其他模块,如Spring Batch(批处理)、Spring Security(安全)、Spring Integration(集成)等。理解并掌握Spring源码,有助于我们更好地利用Spring...
《Spring攻略(第二版)书籍源码》是一个深入学习Spring框架的重要资源,它包含了作者在编写书籍过程中所使用的完整代码示例。这份源码旨在帮助读者更好地理解和实践Spring框架的各种功能和最佳实践。 Spring框架是...
《Spring源码分析》这份资料深入探讨了Spring框架的核心机制,尤其聚焦于Spring5版本。Spring作为Java领域中最重要的轻量级应用框架之一,它的设计理念、实现方式以及工作原理对于任何想成为优秀Java开发者的人都至...
《Spring源码分析》 Spring框架作为Java领域中不可或缺的一部分,其强大之处在于它提供了丰富的功能,包括依赖注入(Dependency Injection,简称DI)、面向切面编程(Aspect-Oriented Programming,简称AOP)、事务...
通过深入学习Spring的源码,我们可以了解到这些特性的实现细节,以及Spring如何优雅地管理对象和处理事务。 在Spring5中,一些重要的改进和新增功能包括: 1. **Reactive编程支持**:Spring5引入了Spring WebFlux...
5. **源码分析**: 在`ProxyFactoryBean`的`getObject()`方法中,会调用`createAopProxy()`生成`AopProxy`,然后`AopProxy`的`getProxy()`方法返回实际的代理对象。`createAopProxy()`会根据配置判断使用JDK还是...
源码分析是深入理解Spring工作原理的关键,以下将对Spring 3.x的源码进行详细的解读。 首先,让我们从核心概念“依赖注入”开始。依赖注入(DI)是Spring框架的基础,它允许组件之间解耦,提高代码的可测试性和可...
Spring框架是开源的轻量级Java应用程序框架,主要目标是简化企业级应用程序的开发。它通过一套完整的设计模式和约定,实现了业务...通过深入分析Spring源码,我们可以更好地理解和利用这些功能来优化我们的应用程序。
Spring5源码分析笔记旨在深入理解Spring的工作原理,帮助开发者提升技能,优化代码,以及更好地利用其核心特性。以下是对Spring5源码的一些关键知识点的详细解释: 1. **依赖注入(Dependency Injection,DI)**:...