`

spring源码学习系列1-spring事务代理深入分析

 
阅读更多
本文主要分析spring事务代理的源码,跟踪代码,了解事务代理的生命周期




1.学习资料和书籍

2.代理的生成(原理)

3.代理的使用-使用中遇到的常见问题


涉及的源码类:
org.springframework.aop.config.AopNamespaceUtils

org.springframework.aop.config.AopConfigUtils

org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator

org.springframework.aop.framework.ProxyConfig

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

org.springframework.aop.support.AopUtils

org.springframework.aop.framework.ProxyFactory

org.springframework.transaction.config.TxNamespaceHandler

org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser

org.springframework.transaction.annotation.AnnotationTransactionAttributeSource

org.springframework.transaction.interceptor.TransactionInterceptor

org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction

org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor



1.学习资料和书籍
grepcode源码及相关博客


2.代理的生成

涉及事务代理的spring元素及特性:


xml配置:
2.1 <tx:annotation-driven transaction-manager="transactionManager" />

当XML中存在“<tx:annotation-driven/>”时,命名空间为tx。从相关的jar包(如spring-tx.jar)中可查看标签处理类。从配置文件spring.handlers中查找到的NamespaceHandler为org.springframework.transaction.config.TxNamespaceHandler
。由TxNamespaceHandler负责具体的解析tx命名空间
部分代码如下:
static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";
static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";
public void init() {
  registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
  registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
  registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
}


解析annotation-driven的类为org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser,源码可查看如下:

http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.transaction/3.2.2/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java?av=f

部分源码如下:
public static final String TRANSACTION_ADVISOR_BEAN_NAME =
			"org.springframework.transaction.config.internalTransactionAdvisor";



AnnotationDrivenBeanDefinitionParser#parse
public BeanDefinition parse(Element element, ParserContext parserContext) {
		String mode = element.getAttribute("mode");
		if ("aspectj".equals(mode)) {
			// mode="aspectj"
			registerTransactionAspect(element, parserContext);
		}
		else {
			// mode="proxy"
			AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
		}
		return null;
	}


查看spring-tx-3.0.xsd可知,mode=proxy。内部类AopAutoProxyConfigurer为实际代理模式下引入aop框架,部分代码如下:






AopAutoProxyConfigurer.configureAutoProxyCreator方法分析:事务定义的入口
AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer#configureAutoProxyCreator
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
			AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);

			String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
			if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
				Object eleSource = parserContext.extractSource(element);

				// Create the TransactionAttributeSource definition.
				RootBeanDefinition sourceDef = new RootBeanDefinition(AnnotationTransactionAttributeSource.class);
				sourceDef.setSource(eleSource);
				sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

				// Create the TransactionInterceptor definition.
				RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
				interceptorDef.setSource(eleSource);
				interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				registerTransactionManager(element, interceptorDef);
				interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
				String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);

				// Create the TransactionAttributeSourceAdvisor definition.
				RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
				advisorDef.setSource(eleSource);
				advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
				advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
				if (element.hasAttribute("order")) {
					advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
				}
				parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);

				CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
				compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
				compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
				compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
				parserContext.registerComponent(compositeDef);
			}
		}





创建InfrastructureAdvisorAutoProxyCreator的beanDefinition
a.定义后置处理器(InfrastructureAdvisorAutoProxyCreator)-根据配置信息,定义生成代理的入口

AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);  

创建事务代理的后置处理器InfrastructureAdvisorAutoProxyCreator






----------------------代码直译start----------------------
第一行:创建名为AUTO_PROXY_CREATOR_BEAN_NAME=org.springframework.aop.config.internalAutoProxyCreator的后置处理器InfrastructureAdvisorAutoProxyCreator(实现了BeanPostProcessor),且名为AUTO_PROXY_CREATOR_BEAN_NAME的后置处理器只有一个

尚未注册,第三行注册


第二行:给AUTO_PROXY_CREATOR_BEAN_NAME设置属性
解析
PROXY_TARGET_CLASS_ATTRIBUTE = "proxy-target-class"
EXPOSE_PROXY_ATTRIBUTE = "expose-proxy"
设置后置处理器相关属性值
proxyTargetClass=true或
exposeProxy=true
(这2个属性在org.springframework.aop.framework.ProxyConfig中)

第三行:注册到容器
----------------------代码直译end----------------------


InfrastructureAdvisorAutoProxyCreator源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/autoproxy/InfrastructureAdvisorAutoProxyCreator.java#InfrastructureAdvisorAutoProxyCreator

AbstractAdvisorAutoProxyCreator源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java#AbstractAdvisorAutoProxyCreator

AbstractAutoProxyCreator源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java#AbstractAutoProxyCreator

执行InfrastructureAdvisorAutoProxyCreator
a.1 AbstractApplicationContext.refresh-执行生成代理的入口,调用以上定义的入口生成代理

单一职责原则:AbstractAutoProxyCreator.postProcessAfterInitialization(Object bean, String beanName)(有图可知AbstractAutoProxyCreator为InfrastructureAdvisorAutoProxyCreator祖先类,祖先类中定义了模板方法),继续调用wrapIfNecessary方法

在实例化bean后,调用初始化方法后执行

该方法中:
(1)获取拦截器主要在后置处理器中完成 (2)创建代理委托给ProxyFactory完成

(1) 首先查找所有符合条件的Advisor类型的类(抽象方法:getAdvicesAndAdvisorsForBean)。
该任务委托由AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean完成(有图可知AbstractAdvisorAutoProxyCreator为AbstractAutoProxyCreator的子类,InfrastructureAdvisorAutoProxyCreator的父类),继续调用findEligibleAdvisors,在该方法中,

(1.1)首先调用findCandidateAdvisors()方法,查找所有advisor类型的类
abstractAutoProxyCreator.postProcessAfterInitialization->abstractAutoProxyCreator.wrapIfNecessary->abstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean->abstractAdvisorAutoProxyCreator.findEligibleAdvisors->abstractAdvisorAutoProxyCreator.findCandidateAdvisors->advisorRetrievalHelper.findAdvisorBeans()->BeanFactoryUtils.beanNamesForTypeIncludingAncestors->beanFactory.getBean(name, Advisor.class)


advisorRetrievalHelper.findAdvisorBeans()方法中,循环advisorNames

BeanFactoryAdvisorRetrievalHelper源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/autoproxy/BeanFactoryAdvisorRetrievalHelper.java#BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans%28%29

(1.2)其次调用findAdvisorsThatCanApply()方法,查找所有上一步中符合条件的advisor。

abstractAutoProxyCreator.postProcessAfterInitialization->abstractAutoProxyCreator.wrapIfNecessary->abstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean->abstractAdvisorAutoProxyCreator.findEligibleAdvisors->abstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply->AopUtils.findAdvisorsThatCanApply->advisor.getPointCut->pointcut.matches->tas.getTransactionAttribute 最终返回符合条件的advisor

AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass)方法,
该方法中循环candidateAdvisors,调用canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions),根据advisor获取pointcut,继续调用canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions),通过pc.getMethodMatcher()获取methodMatcher,这个类是真正判断该类或方法适合符合事物,即该类或方法是否有@Transaction注释

如果bean不适合该advisor,即没有@Transaction注释,则返回false,并将该bean放入this.advisedBeans.put(cacheKey, Boolean.FALSE),并最终返回bean

否则创建代理,(1)最终过滤符合条件的拦截器specificInterceptors


对于BeanFactoryTransactionAttributeSourceAdvisor持有对象TransactionAttributeSourcePointcut,具体分析见(d)




(2) 创建代理AopProxy,并通过aopProxy.getProxy返回最终代理bean。



abstractAutoProxyCreator.postProcessAfterInitialization->abstractAutoProxyCreator.wrapIfNecessary->abstractAutoProxyCreator.createProxy->proxyFactory.getProxy->proxyFactory.createAopProxy().getProxy->jdkDynamicAopProxy.getProxy或cglibProxy.getProxy->java.lang.reflect.Proxy.newProxyInstance(classLoader, proxiedInterfaces, this):  最终返回proxy

this即为aopProxy(jdkDynamicAopProxy或cglibProxy)其实现了InvocationHandler接口

proxy何时调用?
用户业务对象的代理调用时,最终调用invocationHandler.invoke方法

通过jdkDynamicAopProxy源码了解其invoke方法
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/JdkDynamicAopProxy.java#JdkDynamicAopProxy



abstractAutoProxyCreator.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)),在该方法中创建ProxyFactory,并设置属性

ProxyFactory源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/ProxyFactory.java#ProxyFactory.getProxy%28java.lang.ClassLoader%29

ProxyFactory proxyFactory = new ProxyFactory();
		// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
		proxyFactory.copyFrom(this);

		if (!shouldProxyTargetClass(beanClass, beanName)) {
			// Must allow for introductions; can't just set interfaces to
			// the target's interfaces only.
			Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
			for (Class<?> targetInterface : targetInterfaces) {
				proxyFactory.addInterface(targetInterface);
			}
		}

		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		for (Advisor advisor : advisors) {
			proxyFactory.addAdvisor(advisor);
		}

		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}

		return proxyFactory.getProxy(this.proxyClassLoader);

最后一句proxyFactory.getProxy(this.proxyClassLoader);此处创建代理。

public Object getProxy(ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}


该方法中createAopProxy()返回AopProxy如下:
proxyCreatorSupport.createAopProxy()创建代理
protected final synchronized AopProxy createAopProxy() {
	if (!this.active) {
	        activate();
	}
	return getAopProxyFactory().createAopProxy(this);
}


getAopProxyFactory()方法中获取ProxyCreatorSupport的内置对象aopProxyFactory(new DefaultAopProxyFactory())。
DefaultAopProxyFactory源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/DefaultAopProxyFactory.java#DefaultAopProxyFactory

getAopProxyFactory().createAopProxy(this)该方法返回AopProxy
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			Class targetClass = config.getTargetClass();
			if (targetClass == null) {
				throw new AopConfigException("TargetSource cannot determine target class: " +
						"Either an interface or a target is required for proxy creation.");
			}
			if (targetClass.isInterface()) {
				return new JdkDynamicAopProxy(config);
			}
			return CglibProxyFactory.createCglibProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}






createAopProxy().getProxy(classLoader);以jdk生成代理为例
jdkDynamicAopProxy.getProxy(classLoader)
public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
		}
		Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}


最终返回代理对象


JdkDynamicAopProxy源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/JdkDynamicAopProxy.java#JdkDynamicAopProxy

此后置处理器处理@Transaction注释的bean,创建aopProxy。其他advisor如何处理,事务代理的外面再加一层代理?
尝试解释:
该后置处理器可以处理多个advisor(包括事务advisor,即BeanFactoryTransactionAttributeSourceAdvisor)
自定义advisor,实现相应接口,看否是可以识别?
自定义beanpostprocess,在此前代理上创建代理或者覆盖原先代理对象?


ProxyCreatorSupport源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.aop/3.2.2/org/springframework/aop/framework/ProxyCreatorSupport.java#ProxyCreatorSupport.createAopProxy%28%29


断点2





创建AnnotationTransactionAttributeSource的beanDefinition
b.定义AnnotationTransactionAttributeSource-事务属性,每个业务类或方法可能不同,大部分是一样的

// Create the TransactionAttributeSource definition.
				RootBeanDefinition sourceDef = new RootBeanDefinition(AnnotationTransactionAttributeSource.class);
				sourceDef.setSource(eleSource);
				sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

创建AnnotationTransactionAttributeSource定义(事务属性来源于注解@Transactional)

单一职责原则:getTransactionAttribute(Method method, Class<?> targetClass)

判断方法或类是否有@Transactional注释,并解析返回TransactionAttribute或null。其内部调用SpringTransactionAnnotationParser来解析是否有@Transactional注解

AnnotationTransactionAttributeSource源码见:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.transaction/3.2.2/org/springframework/transaction/annotation/AnnotationTransactionAttributeSource.java?av=f

在哪调用其getTransactionAttribute(Method method, Class<?> targetClass)方法,以获取事务属性?
(1) 在后置处理器,avvisor->pointcut.matches->getTransactionAttribute,用于判断advisor适合适合此bean

(2) 在TransactionInterceptor的invoke方法中调用,更确切的说是在TransactionAspectSupport的invokeWithinTransaction方法中。用于事务定义TransactionInfo

用于判断该方法或类是否可开启事务。

还有其他的事务属性来源,应用于不同的事务配置方式如:NameMatchTransactionAttributeSource





创建TransactionInterceptor的beanDefinition
c.定义TransactionInterceptor-事务拦截器,执行事务开始,提交,回滚等操作




// Create the TransactionInterceptor definition.
				RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
				interceptorDef.setSource(eleSource);
				interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				registerTransactionManager(element, interceptorDef);
				interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
				String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);

创建TransactionInterceptor定义

单一职责原则:invoke(final MethodInvocation invocation)

invoke中调用TransactionAspectSupport的invokeWithinTransaction(Method method, Class targetClass, final InvocationCallback invocation)方法,执行真正的拦截逻辑。在该方法中会调用transactionAttributeSource判断类或方法是否可开启事务,调用transactionManager执行拦截逻辑,即开启提交事务等。

registerTransactionManager(element, interceptorDef);
这行代码,主要是设置TransactionAspectSupport的transactionManager(注册事务管理器)。调用invoke时,设置到生成的TransactionInfo中并管理事务状态。

TransactionInterceptor(拦截器)本身不保存数据,只是起到传递的作用,把真正的处理过程交给TransactionAspectSupport 去完成

在哪调用TransactionInterceptor.invoke(final MethodInvocation invocation)?
在(a)处后置处理器中,生成代理(jdk或cglib代理),invoke方法中调用

transactionInterceptor是advice,是否包装成advisor何时包装?
创建代理时(a(2))封装成advisor:
abstractAutoProxyCreator.buildAdvisors->advisorAdapterRegistry.wrap

调用代理方法时,执行的是methodInterceptor,advisor何时拆解成methodInterceptor?
执行代理方法invoke时,通过advised.getInterceptorsAndDynamicInterceptionAdvice获取methodInterceptor,其中会调用advisorAdapterRegistry.getInterceptors(advisor);


TransactionAspectSupport源码可见:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.transaction/3.2.2/org/springframework/transaction/interceptor/TransactionAspectSupport.java#TransactionAspectSupport.TransactionInfo.bindToThread%28%29

joinpointIdentification

TransactionInterceptor源码见:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.transaction/3.2.2/org/springframework/transaction/interceptor/TransactionInterceptor.java#TransactionInterceptor





创建BeanFactoryTransactionAttributeSourceAdvisor的beanDefinition
d.定义BeanFactoryTransactionAttributeSourceAdvisor-事务集成到业务bean,连接中介类





// Create the TransactionAttributeSourceAdvisor definition.
				RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
				advisorDef.setSource(eleSource);
				advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
				advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
				if (element.hasAttribute("order")) {
					advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
				}
				parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);

创建TransactionAttributeSourceAdvisor定义
BeanFactoryTransactionAttributeSourceAdvisor源码:
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.transaction/3.2.2/org/springframework/transaction/interceptor/BeanFactoryTransactionAttributeSourceAdvisor.java?av=f


BeanFactoryTransactionAttributeSourceAdvisor是一个标识类,使其能够被后置处理器(InfrastructureAdvisorAutoProxyCreator见(a)出分析)识别。
具体分析见:
http://www.cnblogs.com/youzhibing/p/6414780.html


持有对象TransactionAttributeSourcePointcut



public boolean matches(Method method, Class targetClass) {
		TransactionAttributeSource tas = getTransactionAttributeSource();
		return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
	}


后置处理器中调用此方法,判断bean或method是否适合此advisor



TransactionAttributeSourcePointcut源码见
http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.transaction/3.1.2/org/springframework/transaction/interceptor/TransactionAttributeSourcePointcut.java#TransactionAttributeSourcePointcut






创建CompositeComponentDefinition的beanDefinition
e.定义组件之间的关系bean

CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
				compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
				compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
				compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
				parserContext.registerComponent(compositeDef);


该类的具体作用是什么?
定义事务处理之间的关系?

断点4:






总结:
条件语句里面创建了3个bean定义(TransactionAttributeSource ,TransactionInterceptor,TransactionAttributeSourceAdvisor ),将3个类组合嵌入compositeDef中,代表整个<tx:annotation-driven transaction-manager="transactionManager" />

还创建了一个后置处理器,bean实例化后,创建事务代理

创建3个定义或者后置处理器的过程中,多处可以继续跟踪代码,如如何创建aopProxy代理,transactioninterceptor中的invoke方法是如何执行的等等。限于篇幅,这里进一步跟踪,后续补上



2.2 @Transactionl
事务属性来源,主要在TransactionAttributeSource中判断bean或者method中是否有注解






3.代理的使用-使用中遇到的常见问题





参考:
https://www.ibm.com/developerworks/cn/education/opensource/os-cn-spring-trans/

http://www.myexception.cn/open-source/1942796.html

http://www.codeceo.com/article/software-outsourcing-and-lover.html

http://blog.csdn.net/qq418517226/article/details/51282035

http://jinnianshilongnian.iteye.com/blog/1901694

http://www.cnblogs.com/wade-luffy/p/6080183.html   Spring事务解析2-标签解析

http://jinnianshilongnian.iteye.com/blog/1508018   TransactionAttributeSource

http://lgbolgger.iteye.com/blog/2180251       Spring事务源码分析(一)Spring事务入门
  • 大小: 9.3 KB
  • 大小: 35.3 KB
  • 大小: 15.9 KB
  • 大小: 17.2 KB
  • 大小: 10.1 KB
  • 大小: 7.8 KB
  • 大小: 12.6 KB
  • 大小: 16.2 KB
分享到:
评论

相关推荐

    官方原版源码 spring-5.2.8.RELEASE.zip

    总的来说,Spring框架5.2.8.RELEASE源码的学习是一次深入理解Java企业级开发、掌握模块化设计和面向切面编程理念的宝贵机会。通过深入研究源码,开发者可以提升自己的编程技巧,为开发高质量的、可维护的应用程序...

    spring-framework-1.0-m1.zip源码

    《Spring框架1.0源码解析》 Spring框架,作为Java企业级应用开发的重要支柱,自2003年发布以来,已经历了多个版本的迭代,为开发者...通过深入学习,我们可以更好地利用Spring的强大功能,提高软件开发的质量和效率。

    spring源码spring-framework-4.2.5.RELEASE

    深入理解Spring源码需要对Java反射、动态代理、设计模式等有扎实的基础。建议从以下几个步骤入手: 1. 了解基本架构和模块划分。 2. 分析核心类如ApplicationContext、BeanFactory和DispatcherServlet的实现。 3. ...

    spring1.2.6源码

    通过阅读和分析Spring 1.2.6的源码,不仅可以学习到Spring的核心设计原则,还能了解到设计模式的运用,例如工厂模式、单例模式、观察者模式等。同时,这也是提升Java编程技巧和理解框架底层运作的好机会。在实际的...

    Tom_深入分析Spring源码

    《Spring源码分析》这份资料深入探讨了Spring框架的核心机制,尤其聚焦于Spring5版本。Spring作为Java领域中最重要的轻量级应用框架之一,它的设计理念、实现方式以及工作原理对于任何想成为优秀Java开发者的人都至...

    官方原版源码 spring-framework-5.2.9.RELEASE.zip

    总的来说,深入学习Spring Framework 5.2.9.RELEASE的源码,不仅可以帮助我们更好地利用这个框架,还能提升我们的编程水平和系统设计能力,从而在实际项目中游刃有余。通过细致研究每个模块的功能和实现细节,我们...

    spring-data-hadoop-1.0.0源码包

    深入学习Spring Data Hadoop的源码,不仅可以帮助我们更好地理解和使用这个库,还能提升我们对Hadoop生态系统的理解。源码中的注释和设计模式将引导我们深入到Hadoop的内部工作原理,同时也会展示Spring如何通过其...

    官方源码 spring-framework-5.2.15.RELEASE.zip

    通过深入学习Spring Framework 5.2.15.RELEASE的源码,开发者不仅可以提升自身的技术能力,也能更好地利用Spring框架解决实际开发中遇到的问题,提高代码质量和开发效率。在后续的开发过程中,对源码的理解也会为...

    官方原版源码spring-framework-5.1.4.RELEASE.zip

    《Spring Framework 5.1.4源码深度解析》 Spring Framework是Java开发中的核心框架,它为构建高质量的企业级应用提供了全面的...通过深入研究源码,我们可以学习到软件设计的最佳实践,提升我们的编程技巧和架构能力。

    spring源码合集spring源码合集

    我们将学习Spring如何与MyBatis无缝集成,以及MyBatis的SQL执行流程,这对于理解数据访问层的优化和事务管理具有重要意义。 5. **Spring底层架构核心概念解析**:"03-Spring之底层架构核心概念解析-周瑜"涵盖了...

    咕泡学院_Tom_JavaVIP课程_深入分析Spring源码(第一阶段)1

    【Spring 框架概述】 Spring 是一个广泛使用的开源 Java 应用开发框架,它的核心目标是简化企业级应用的开发。...通过深入学习 Spring 源码,开发者可以更好地理解其工作原理,进一步优化和定制应用的实现。

    spring系列教程博客源码-东离与糖宝

    "spring系列教程博客源码-东离与糖宝"很显然是一份关于Spring框架的教程资源,其中可能包含了详细的代码示例、解释以及教学内容,旨在帮助学习者深入理解和掌握Spring的核心功能和使用技巧。 1. **Spring核心概念**...

    spring学习事务源码

    本文将深入探讨Spring事务管理的源码,理解其背后的实现机制。 首先,Spring事务管理有两种主要模式:编程式事务管理和声明式事务管理。编程式事务管理通过调用`PlatformTransactionManager`接口提供的方法进行显式...

    官方原版源码 spring-5.2.6.RELEASE.zip

    压缩包中的"spring-5.2.6.RELEASE-docs.zip"包含了完整的API文档和用户指南,是学习和理解Spring源码的重要参考资料。"spring-5.2.6.RELEASE-schema.zip"则包含框架使用的XML schema定义,帮助开发者理解和编写配置...

    官方原版源码spring-framework-4.3.22.RELEASE.zip

    1. **了解设计模式**:Spring源码中广泛应用了设计模式,如工厂模式、单例模式、装饰者模式等,理解这些模式有助于理解源码。 2. **阅读核心类**:从BeanFactory和ApplicationContext开始,逐步深入到AOP、Web MVC等...

    spring-cglib-repack-3.2.6.jar和spring-objenesis-repack-2.6.jar

    在深入探讨Spring框架的核心组件和工作原理时,我们经常会遇到需要构建或运行Spring源码的情况。Spring-cglib-repack-3.2.6.jar和spring-objenesis-repack-2.6.jar是两个至关重要的依赖库,它们在Spring框架的内部...

    spring-framework-2.5.6-with-dependencies

    深入理解Spring源码,可以更好地掌握其设计理念和实现机制。2.5.6版本的源码包含了Spring的主要模块,如Core Container、Data Access/Integration、AOP、Web等。通过对这些模块的分析,我们可以了解到: - 如何通过...

    spring-framework-2.5-rc2-with-dependencies\spring-framework-2.5-rc2\spring-framework-2.5-rc2源代码

    通过阅读和学习这些源码,开发者可以了解到Spring如何实现IoC容器、AOP代理、事件机制、任务调度等多个关键功能。同时,这也有助于开发者更好地理解和使用Spring提供的API,以及在实际项目中如何定制和扩展Spring。 ...

    spring源码解读-地址.txt

    根据提供的文件信息,本次解读将围绕Spring框架的核心概念与源码分析进行展开。Spring框架作为Java企业级开发中不可或缺的一部分,其源码的学习对于深入...希望以上内容能够为大家学习Spring源码提供一定的参考和帮助。

    spring github打包源码 spring-framework-5.3.4.zip

    《深入剖析Spring Framework 5.3.4源码》 Spring Framework是Java开发中的核心框架,它为构建高质量、可维护的应用程序提供了全面的支持。在本文中,我们将深入探讨Spring Framework 5.3.4的源码,了解其设计理念、...

Global site tag (gtag.js) - Google Analytics