文档章节

Spring 事务初始化源码分析

TSMYK
 TSMYK
发布于 01/19 17:30
字数 3351
阅读 159
收藏 4

相关文章

Spring 事务使用详解

文本首发地址为公众号:Java技术大杂烩,欢迎关注。

前言

在上篇文章 Spring 事务使用详解 中详细介绍了 Spring 事务的使用过程,而今天就来看下 Spring 事务是如何来实现,比如 Spring 事务在初始化的时候做了什么,Spring 事务是如何进行事务的提交和回滚的;为了避免篇幅太长,所以分开两篇文章进行分析,这篇文章先来分析下 Spring 事务是如何初始化的,在初始化的时候做了什么。

注册 InfrastructureAdvisorAutoProxyCreator

我们知道,想要使用 Spring 事务,就得开启 Spring 的事务功能,如果是配置文件的方式,则需要在配置文件中配置 <tx:annotation-driven /> 标签,那么分析 Spring 事务初始化就从解析该标签开始。

在 TxNamespaceHandler 类的 init 方法中可以看到解析该标签的代码逻辑:

public class TxNamespaceHandler extends NamespaceHandlerSupport {
    // .......
	@Override
	public void init() {
		registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
		registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
		registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
	}
}

所以,当在解析  <tx:annotation-driven /> 标签的时候,会使用 AnnotationDrivenBeanDefinitionParser 类的 parse 方法来进行解析:

// AnnotationDrivenBeanDefinitionParser.java

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

接下来看下proxy模式,即默认模式的解析;使用的是它的内部类 AopAutoProxyConfigurer 的 configureAutoProxyCreator 方法进行解析:

public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
	AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
    // ...............
}

在该方法中,第一行就是进行注册 InfrastructureAdvisorAutoProxyCreator,还有其他的bean的注册,这里先不管;先来看下注册过程:

public static void registerAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
    // 注册
	BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
			parserContext.getRegistry(), parserContext.extractSource(sourceElement));
    // 处理proxy-target-class和 expose-proxy属性
	useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
    // ......
}

这里和 Spring AOP 的处理流程是一样的,显示注册目标bean,再处理 proxy-target-classexpose-proxy 属性,可以参考 Spring AOP 注解方式源码解析 ,注册 AopConfigUtils.registerAutoProxyCreatorIfNecessary:

public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry 
			registry,Object source) {
	return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}

private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, 
				BeanDefinitionRegistry registry,Object source) {
    // 处理优先级
	if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
		BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
		if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
			int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
			int requiredPriority = findPriorityForClass(cls);
			if (currentPriority < requiredPriority) {
				apcDefinition.setBeanClassName(cls.getName());
			}
		}
		return null;
	}
	// 注册
	RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
	beanDefinition.setSource(source);
	beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
	beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
	return beanDefinition;
}

关于该bean的作用下面分析,再 AopAutoProxyConfigurer 的 configureAutoProxyCreator 方法中除了注册该bean,还注册了三个bean,这三个bean用来支撑Spring的整个事务功能:

public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
    // 注册 InfrastructureAdvisorAutoProxyCreator
	AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
	// 事务AdvisorBeanName
	String txAdvisorBeanName = "org.springframework.transaction.config.internalTransactionAdvisor";
	if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
	    // 注册 AnnotationTransactionAttributeSource
		Object eleSource = parserContext.extractSource(element);
		RootBeanDefinition sourceDef = new RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
		sourceDef.setSource(eleSource);
		sourceDef.setRole(2);
		String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
		// 注册 TransactionInterceptor
		RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
		interceptorDef.setSource(eleSource);
		interceptorDef.setRole(2);
		AnnotationDrivenBeanDefinitionParser.registerTransactionManager(element, interceptorDef);
		interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
		String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
		// 注册 BeanFactoryTransactionAttributeSourceAdvisor
		RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
		advisorDef.setSource(eleSource);
		advisorDef.setRole(2);
		// 并把上面注册的两个bean当作该bean的属性
		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);
        // 注册其他的事件通知组件
	}
}

这三个 bean 关系如下:

InfrastructureAdvisorAutoProxyCreator

这个类是什么意思呢?它有什么用呢?按照类名来理解就是 基础的 Advisor 自动代理创建器,对于自定义的 Advisor,则不用它来创建,它的类图如下:

可以看到它实现了 BeanPostProcessor 接口,而在前面分析 Spring 相关源码的时候知道,该接口是 Spring 提供了一个扩展接口,有两个方法:

public interface BeanPostProcessor {
    // bean 初始化之前执行
	default Object postProcessBeforeInitialization(Object bean, String beanName){
		return bean;
	}
    // bean 初始化之后执行
	default Object postProcessAfterInitialization(Object bean, String beanName) {
		return bean;
	}
}

所以,当我们定义的一个 bean 初始化完成后,就会执行 postProcessAfterInitialization 方法,而 InfrastructureAdvisorAutoProxyCreator 类实现了该方法:

public Object postProcessAfterInitialization(Object bean, String beanName) {
	if (bean != null) {
        // 根据 beanClassName 和 beanName 创建一个key
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (!this.earlyProxyReferences.contains(cacheKey)) {
            // 包装 bean
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

// 包装bean
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    // 已经处理过了,直接返回
	if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
    // 该 bean不需要增强,直接返回
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		return bean;
	}
    // 是否是Advice.class, Pointcut.class, Advisor.class, AopInfrastructureBean.class 这几个类,如果是
    // 这几个类,或者该bean需要跳过的,则直接返回
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}
	// 如果有增强,则创建代理
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	if (specificInterceptors != DO_NOT_PROXY) {
		this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 创建代理
		Object proxy = createProxy(
				bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
		this.proxyTypes.put(cacheKey, proxy.getClass());
        // 返回代理
		return proxy;
	}
	this.advisedBeans.put(cacheKey, Boolean.FALSE);
	return bean;
}

// 创建代理
protected Object createProxy(Class<?> beanClass, String beanName,
		 Object[] specificInterceptors, TargetSource targetSource) {
    // ....
	ProxyFactory proxyFactory = new ProxyFactory();
	proxyFactory.copyFrom(this);
	if (!proxyFactory.isProxyTargetClass()) {
		if (shouldProxyTargetClass(beanClass, beanName)) {
            // CGLIB 代理
			proxyFactory.setProxyTargetClass(true);
		}
		else {
            // JDK接口代理
			evaluateProxyInterfaces(beanClass, proxyFactory);
		}
	}
    // 创建代理
	return proxyFactory.getProxy(getProxyClassLoader());
}

// 真正创建代理
public Object getProxy(ClassLoader classLoader) {
	return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
    //.....
	return getAopProxyFactory().createAopProxy(this);
}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    // 判断 CGLIB 代理和 JDK 代理的条件
	if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
		Class<?> targetClass = config.getTargetClass();
        // JDK 代理
		if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
			return new JdkDynamicAopProxy(config);
		}
        // CGLIB 代理
		return new ObjenesisCglibAopProxy(config);
	}
	else {
        // JDK 代理
		return new JdkDynamicAopProxy(config);
	}
}

上述的这段代码,当我们的 bean 初始化完成后,就会为该 bean 创建代理,创建代理的时候,根据配置条件创建 JDK 动态代理或者 CGLIB 代理

Spring 代理创建参考 Spring AOP 创建代理的源码解析

但是,是不是所有的 bean 都会创建代理呢,不是的,在包装 bean 的方法 wrapIfNecessary 中,会去查找该bean对应的增强,如果有相应的增强,则才会去创建代理,所有说在创建代理之前,会先去查找该 bean 对应的增强(拦截器),在 wrapIfNecessary 方法中有该代码:

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

对于 Spring 事务来说,该方法返回 specificInterceptors  不可能为空,所以才会走后面创建代理的逻辑。

接下来看下该方法的实现过程,即查询对应 class 或 method 的增强器。

查询对应 class 或 method 的增强器

在 getAdvicesAndAdvisorsForBean 方法中,第一步,要找出符合条件的增强器,第二步,需要判断增强器是否符合要求。

protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName,TargetSource targetSource) {
    // 根据 className 和 beanName 找出符合条件的增强器
	List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
	if (advisors.isEmpty()) {
		return DO_NOT_PROXY;
	}
	return advisors.toArray();
}

// 找出增强器
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    //查找增强器
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
    //判断增强器是否符合条件
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    //.......
	return eligibleAdvisors;
}

查找增强器 findCandidateAdvisors:

protected List<Advisor> findCandidateAdvisors() {
	return this.advisorRetrievalHelper.findAdvisorBeans();
}

public List<Advisor> findAdvisorBeans() {
	String[] advisorNames = this.cachedAdvisorBeanNames;
	if (advisorNames == null) {
	    // 获取所有 Advisor.class 类 
		// 在前面注册的 bean:BeanFactoryTransactionAttributeSourceAdvisor 也是一个 Advisor,
		// 所以,在这里该 bean 会被提取出来,后续一起植入代理
		advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);
		this.cachedAdvisorBeanNames = advisorNames;
	}
	List<Advisor> advisors = new ArrayList<>();
	for (String name : advisorNames) {
	   // 判断增强器bean是否符合条件,这里返回true 
	   if (isEligibleBean(name)) {
	     if (this.beanFactory.isCurrentlyInCreation(name)) {
			//跳过正在创建的增强器
	   	 }
		 else {
	 		advisors.add(this.beanFactory.getBean(name, Advisor.class));
     	 }
	   }
	}
	return advisors;
}

这里要说明一下,在前面注册的bean:BeanFactoryTransactionAttributeSourceAdvisor,它也是一个 Advisor,所以在获取所有的  Advisor.class 类的时候,也会把该 bean 提取出来;此外,该 bean 还拥有 AnnotationTransactionAttributeSource 和 TransactionInterceptor 这两个 bean,后面会一起被织入代理。

当查找到所有的增强后,需要判断哪些增强符合我们的目标 bean,对应方法 findAdvisorsThatCanApply:

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
    // 用来存放符合条件的增强
	List<Advisor> eligibleAdvisors = new ArrayList<>();
    // 处理引介增强
	for (Advisor candidate : candidateAdvisors) {
		if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
			eligibleAdvisors.add(candidate);
		}
	}
	boolean hasIntroductions = !eligibleAdvisors.isEmpty();
	for (Advisor candidate : candidateAdvisors) {
		if (candidate instanceof IntroductionAdvisor) {
			// 在处理引介增强时已经处理过了
			continue;
		}
        // 普通的bean
		if (canApply(candidate, clazz, hasIntroductions)) {
			eligibleAdvisors.add(candidate);
		}
	}
	return eligibleAdvisors;
}

canApply 方法:

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
	if (advisor instanceof IntroductionAdvisor) {
		return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
	}
	else if (advisor instanceof PointcutAdvisor) {
        /// pca=BeanFactoryTransactionAttributeSourceAdvisor
		PointcutAdvisor pca = (PointcutAdvisor) advisor;
        //pca.getPointcut()=TransactionAttributeSourcePointcut
		return canApply(pca.getPointcut(), targetClass, hasIntroductions);
	}
	else {
		return true;
	}
}

对于一个事务 bean 来说,该增强 Advisor 就是前面注册的  BeanFactoryTransactionAttributeSourceAdvisor,而该 bean 实现了 PointcutAdvisor 接口,所以会通过 第二个 if 判断;之后 通过 getPointcut 得到 TransactionAttributeSourcePointcut 对象继续调用 重载的 canApply 方法如下:

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
	// 获取方法匹配器
    // 此时的匹配器是 TransactionAttributeSourcePointcut
	MethodMatcher methodMatcher = pc.getMethodMatcher();
	// 如果可以匹配所有方法,则不再循环方法进行判断
	if (methodMatcher == MethodMatcher.TRUE) {
		return true;
	}
    // 存放目标类和目标类所有的接口
	Set<Class<?>> classes = new LinkedHashSet<>();
	if (!Proxy.isProxyClass(targetClass)) {
		classes.add(ClassUtils.getUserClass(targetClass));
	}
	classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
    // 遍历目标类和目标类所有的接口下的方法,如果有任何一个方法能够符合增强器的要求,则直接返回
	for (Class<?> clazz : classes) {
	  Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
	  for (Method method : methods) {
	    if (introductionAwareMethodMatcher != null ? 
		  introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
		  // 匹配方法是否满足条件
 		  methodMatcher.matches(method, targetClass)) {
		return true;
		}
	  }
	}
	return false;
}

到这里,只看到了根据方法去判断是否符合增强器,没有根据类来和接口判断,因为事务注解 Translation 可以放在类或接口上,对其下的所有public方法有用;其实,对类和接口的判断条件在是在 matcher 方法里面,调用的使用 TransactionAttributeSourcePointcut 的 mathcer 方法:

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

这里的 tas 就是 AnnotationTransactionAttributeSource,即在文章开头注册的那三个 bean 之一,它的 getTransactionAttribute 如下,去获取事务:

public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) {
	// 忽略 Object 的方法
	if (method.getDeclaringClass() == Object.class) {
		return null;
	}
	// 根据method和class来创建key
	Object cacheKey = getCacheKey(method, targetClass);
	// 根据key查询事务,
	TransactionAttribute cached = this.attributeCache.get(cacheKey);
	if (cached != null) {
	   //...
	   // 已经判断过了
	   return cached;
	}
	else {
	   TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
	   //....
	   return txAttr;
	}
}

computeTransactionAttribute 方法如下:

protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
	// 不是public方法,则跳过
	if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
		return null;
	}
	// 实现类的方法
	Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

	// 首先在实现类的方法上查询注解,查询到,则直接返回
	TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
	if (txAttr != null) {
		return txAttr;
	}

	// 如果在实现类对应方法上找不到注解,则在方法的实现类上查找注解,找到直接返回
	txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
	if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
		return txAttr;
	}
    // 存在接口
	if (specificMethod != method) {
		// 在接口方法上查找注解,找到直接返回
		txAttr = findTransactionAttribute(method);
		if (txAttr != null) {
			return txAttr;
		}
		// 如果在接口方法上找不到注解,则在接口上查找注解
		txAttr = findTransactionAttribute(method.getDeclaringClass());
		if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
			return txAttr;
		}
	}
	return null;
}

在上述的 computeTransactionAttribute 方法中,可以看到,去查找是一个事务方法,首先在实现类的方法上查找,找到直接返回,如果还找不到,则在实现类上查找注解;如果在实现类上找不到,再到接口上的方法里面去找,如果接口方法还找不到,则再接口上查找;所以,在这里可以看到,放在类或接口上事务注解可以作用于其下的所有 public 方法,且 方法上的事务注解要优先于类或接口上的注解,即如果再类,接口和方法上都加上事务注解,则会以方法上的注解为准,其次是 类,最后才是接口。

之后,就是去解析注解的属性,对应方法为:findTransactionAttribute,

protected TransactionAttribute findTransactionAttribute(Method method) {
	return determineTransactionAttribute(method);
}
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
    // 事务注解解析器
	for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
		TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
		if (attr != null) {
			return attr;
		}
	}
	return null;
}

// 方法上获取 Transactional 注解
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
    // 在方法上获取 Transactional 注解
	AnnotationAttributes attributes =
		AnnotatedElementUtils.findMergedAnnotationAttributes(element, Transactional.class, false, false);
	if (attributes != null) {
	    // 解析 Transactional 注解属性
		return parseTransactionAnnotation(attributes);
	}
	else {
		return null;
	}
}

// 解析 Transactional 注解属性
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
	RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();

	Propagation propagation = attributes.getEnum("propagation");
	rbta.setPropagationBehavior(propagation.value());
	Isolation isolation = attributes.getEnum("isolation");
	rbta.setIsolationLevel(isolation.value());
	rbta.setTimeout(attributes.getNumber("timeout").intValue());
	rbta.setReadOnly(attributes.getBoolean("readOnly"));
	rbta.setQualifier(attributes.getString("value"));

	List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
	for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
		rollbackRules.add(new RollbackRuleAttribute(rbRule));
	}
	for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
		rollbackRules.add(new RollbackRuleAttribute(rbRule));
	}
	for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
		rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
	}
	for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
		rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
	}
	rbta.setRollbackRules(rollbackRules);
	return rbta;
}

在这里就可以看到,事务注解 Transaction 的各种各样的属性了。

当然,到这里还没有完;到这里,可以从下往上看下所有的代码,当方法存在 Transaction 注解的时候,该方法 就会满足增强器 BeanFactoryTransactionAttributeSourceAdvisor ,之后就会为我们的目标bean 创建代理,并把 增强器  BeanFactoryTransactionAttributeSourceAdvisor 织入到代理中,进而来影响我们的业务逻辑。

总结

这篇文章主要介绍了 Spring 事务的初始化功能,在 Spring 加载的时候,会注册 InfrastructureAdvisorAutoProxyCreator bean,而该 bean 又实现了 BeanPostProcessor 接口,所以当目标bean在初始化完成后,会执行 postProcessAfterInitialization 方法,在该方法中,会去遍历我们的目标 bean 中的方法,如果方法上有 Translaction 事务注解,则会为目标 bean 创建代理,并把 增强器  BeanFactoryTransactionAttributeSourceAdvisor 织入到代理中;当然,BeanFactoryTransactionAttributeSourceAdvisor  该 bean 还拥有 AnnotationTransactionAttributeSource 和 TransactionInterceptor  这两个 bean,会一起被织入代理。

所以在 Spring 事务初始化的过程中,主要注册了四个 bean:

1. InfrastructureAdvisorAutoProxyCreator

2. BeanFactoryTransactionAttributeSourceAdvisor  

3. AnnotationTransactionAttributeSource

4. TransactionInterceptor 

InfrastructureAdvisorAutoProxyCreator 主要是用来查找方法,类或者接口上的事务注解 Translaction,如果存在注解,则为目标bean创建代理,并把其他的三个 bean 织入到代理中,而另外的三个 bean 主要是用来 执行目标方法,进行事务的提交和回滚。

关于使用 BeanFactoryTransactionAttributeSourceAdvisor,AnnotationTransactionAttributeSource,TransactionInterceptor  来执行目标方法,提交事务,回滚事务,则在下一篇文章中分析。

 

© 著作权归作者所有

共有 人打赏支持
TSMYK
粉丝 87
博文 79
码字总数 194573
作品 0
成都
程序员
私信 提问
Spring 事务提交回滚源码解析

前言 在上篇文章 Spring 事务初始化源码分析 中分析了 Spring 事务初始化的一个过程,当初始化完成后,Spring 是如何去获取事务,当目标方法异常后,又是如何进行回滚的,又或是目标方法执行...

TSMYK
01/20
0
0
Spring的事务管理实现原理初探

这里主要是通过分析部分源码进行剖析Spring事务管理的实现原理。 再分析源码前,现从理论上大概分析哈: 纯JDBC操作数据库的基本步骤: 1. 获取连接 Connection conn = DriverManager.getCon...

rockypeng
2014/01/19
0
0
分布式事务系列(开篇)提出疑问和研究过程

1 前言 系列目录 - 分布式事务系列(开篇)提出疑问和研究过程- 分布式事务系列(1.1)Spring事务管理器PlatformTransactionManager源码分析- 分布式事务系列(1.2)Spring事务体系- 分布式事...

乒乓狂魔
2015/05/12
0
6
早前学习Java记录

Spring 对 iBATIS 的支持】 Spring 通过 DAO 模式,提供了对 iBATIS 的良好支持。 SqlMapClient:是 iBATIS 中的主要接口,通过 xml 配置文件可以让 Spring 容器来管理 SqlMapClient 对象的创...

大风厂蔡成功
2016/07/10
43
0
InitializingBean的作用

最近工作需要得到sping中的每个事物需要执行的sql,称机会简单研究了一下spring的事务,项目中管理事务比较简单,用TransactionTemplate,就直接以TransactionTemplate为入口开始学习。 Tran...

哲别0
2017/10/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

极路由4刷OpenWrt(LEDE)

申请开发者模式 登录路由器后台 进入插件中间 选中路由器信息 申请开发者权限 安装开发者插件 刷 Bootloader 下载 极路由4 的 Breed 通过SSH登录路由器 (必须安装开发者插件,端口 1022 账号...

dingdayu
32分钟前
3
0
浅淡个人学习嵌入式Linux过程

我专业是电子信息工程,在初入大学的时候,我们的班主任便要我们多多去了解一些关于电子方面的知识。后来我了解到了嵌入式,继而了解到了嵌入式Linux。其实我们学习linux差不多就学习linux内...

linux-tao
今天
7
0
SpringBoot使用GraphQL简单学习-1

官网 一、GraphQL简介 1.GraphQL是什么? GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够...

wind2012
今天
5
0
Android的WIFI局域网对讲机

https://blog.csdn.net/z979451341/article/details/79280749 (三)Android局域网内语音对讲 基于UDP语音传输 https://blog.csdn.net/stormxiaofeng/article/details/80513947 Android7.0手......

shzwork
今天
2
0
vuex

一直有个误区 vuex既然页面刷新会丢失 那还有什么意义 。 重新翻看了下文档才恍然大误,vuex主要解决的是不同组件间的通信。 跨页面数据共享本质上还是用sessionStorage/localStorage...

东东笔记
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部