惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Commits to openclaw:main
Recent Commits to openclaw:main
SecWiki News
SecWiki News
Webroot Blog
Webroot Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
N
News and Events Feed by Topic
Recent Announcements
Recent Announcements
Help Net Security
Help Net Security
Jina AI
Jina AI
O
OpenAI News
雷峰网
雷峰网
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
博客园 - 三生石上(FineUI控件)
W
WeLiveSecurity
Schneier on Security
Schneier on Security
T
Threat Research - Cisco Blogs
IT之家
IT之家
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Vercel News
Vercel News
N
News and Events Feed by Topic
T
The Exploit Database - CXSecurity.com
爱范儿
爱范儿
Recorded Future
Recorded Future
Google Online Security Blog
Google Online Security Blog
TaoSecurity Blog
TaoSecurity Blog
美团技术团队
Engineering at Meta
Engineering at Meta
Security Latest
Security Latest
V
V2EX
T
Tailwind CSS Blog
P
Privacy & Cybersecurity Law Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
Schneier on Security
B
Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 【当耐特】
PCI Perspectives
PCI Perspectives
GbyAI
GbyAI
I
Intezer
Spread Privacy
Spread Privacy
Security Archives - TechRepublic
Security Archives - TechRepublic
Cloudbric
Cloudbric
V
Visual Studio Blog
MongoDB | Blog
MongoDB | Blog
Forbes - Security
Forbes - Security
The Last Watchdog
The Last Watchdog
aimingoo的专栏
aimingoo的专栏
C
CERT Recently Published Vulnerability Notes
A
About on SuperTechFans
罗磊的独立博客

博客园 - daidaidaiyu

ZooKeepper 一文入门 ThingsBoard 规则链系统源码分析和自定义定时器 嵌入式开发入门知识 一文入门和实践Kafka 一文学习入门 ThingsBoard 开源物联网平台 Claude Code 使用一则 JMS, ActiveMQ 学习一则 Nacos实例一则及其源码环境搭建 一文学习 工作流开发 BPMN、 Flowable 一文学习 Spring 声明式事务源码全流程总结 Spring IOC 源码学习 事务增强相关的对象创建 Spring IOC 源码学习 事务相关的 BeanDefinition 解析过程 (XML) GIS 核心知识 23.行为型 - 访问者模式 (Visitor Pattern) 一文学习 Spring AOP 源码全过程 22.行为型 - 迭代器模式 (Iterator Pattern) 21.行为型 - 状态模式 (State Pattern) Netty 核心知识 SpringCloud 微服务实现一则 (Eureka + Hystrix) 20.行为型 - 责任链模式(ChainofResponsibility Pattern) Modbus 协议 学习一则 - daidaidaiyu 19.行为型 - 策略模式(Strategy Pattern) - daidaidaiyu Redis 学习一则 - daidaidaiyu Android NDK 开发一则 - daidaidaiyu
Spring IOC 源码学习 声明式事务的入口点
daidaidaiyu · 2026-03-20 · via 博客园 - daidaidaiyu

一、Spring 声明式事务的入口点

对于XML入口点

XML配置定义

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:aop="http://www.springframework.org/schema/aop"
	   xmlns:tx="http://www.springframework.org/schema/tx"
	   xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/tx
		https://www.springframework.org/schema/tx/spring-tx.xsd
		http://www.springframework.org/schema/aop
		https://www.springframework.org/schema/aop/spring-aop.xsd">
	<tx:annotation-driven></tx:annotation-driven>

	<!-- dao bean-->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
		<property name="dataSource" ref = "dataSource"></property>
	</bean>

	<!-- service bean-->
	<bean id="bookService" class="org.yang.learn.spring.tx.BookService" >
		<property name="jdbcTemplate" ref="jdbcTemplate"></property>
	</bean>
	<!-- 数据源 bean-->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" >
		<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
		<property name="url"
				  value="jdbc:mysql://192.168.40.171:3306/workflow_test?serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8&amp;useSSL=false"/>
		<property name="username" value="user_dev"></property>
		<property name="password" value="dev-sny.com"></property>
	</bean>
	<!-- 事务管理bean-->
	<bean id="transactionManager" class="org.springframework.jdbc.support.JdbcTransactionManager" >
		<constructor-arg ref="dataSource"></constructor-arg>
	</bean>
	<aop:config>
		<!--切点配置	-->
		<aop:pointcut id="serviceOperation"
					  expression="execution(* org.yang.learn.spring.tx.BookService.*(..))"/>
		<!-- 通知/增强 配置 (关键是这个通知指向 txAdvice '事务增强')-->
		<aop:advisor pointcut-ref="serviceOperation"  advice-ref="txAdvice"/>
	</aop:config>

	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="get*" read-only="true"/>
			<tx:method name="insertWithTransaction" propagation="REQUIRED" />
			<tx:method name="insertWithNoTransaction" propagation="NEVER" />
		</tx:attributes>
	</tx:advice>
</beans>

在XML中配置 tx:.. 启用tx标签, 在解析XML自定义标签时, 会拿到 TxNamespaceHandler 命名空间处理器, 其主要工作就是注册事务相关的标签的解析器

  • tx:advice 标签解析器:负责XML相关的标签解析 TxAdviceBeanDefinitionParser
  • tx:annotation-driven 标签解析器:负责注解相关的解析 AnnotationDrivenBeanDefinitionPar

org.springframework.transaction.config.TxNamespaceHandler

public class TxNamespaceHandler extends NamespaceHandlerSupport {

	static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";

	static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";


	static String getTransactionManagerName(Element element) {
		return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ?
				element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME);
	}


	@Override
	public void init() {
		//  <tx:advice> 标签解析器:负责解析XML <tx:advice> 事务标签配置 TxAdviceBeanDefinitionParser
		registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
		//  <tx:annotation-driven> 标签解析器:负责解析注解相关的事务配置 AnnotationDrivenBeanDefinitionParser
		registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
		// JTA 规范的分布式事务管理器(管理跨多个资源的事务) TODO
		registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
	}
}

启用事务注解支持

class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {

	/**
	 * Parses the {@code <tx:annotation-driven/>} tag. Will
	 * {@link AopNamespaceUtils#registerAutoProxyCreatorIfNecessary register an AutoProxyCreator}
	 * with the container as necessary.
	 */
	@Override
	@Nullable
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		registerTransactionalEventListenerFactory(parserContext);
		String mode = element.getAttribute("mode");
		if ("aspectj".equals(mode)) {
			// mode="aspectj"
			registerTransactionAspect(element, parserContext);
			if (ClassUtils.isPresent("jakarta.transaction.Transactional", getClass().getClassLoader())) {
				registerJtaTransactionAspect(element, parserContext);
			}
		}
		else {
			// 默认是  proxy 模式
			// mode="proxy"
			AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
		}
		return null;
	}
	

注册三剑客

/**
 * Inner class to just introduce an AOP framework dependency when actually in proxy mode.
 */
private static class AopAutoProxyConfigurer {

	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(
					"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
			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);

			/**
			 * 其中构建事务增强器(BeanFactoryTransactionAttributeSourceAdvisor)
			 * - **Pointcut(切点)**: 默认匹配所有标注 `@Transactional` 的类 / 方法(由 `TransactionAttributeSourcePointcut` 实现)
			 * - **Advice(通知)**: 即 `TransactionInterceptor`(事务拦截器)
			 * - **TransactionAttributeSource(注解解析器)**:即 `AnnotationTransactionAttributeSource`, 负责解析 `@Transactional` 注解的属性(传播行为、隔离级别等)。
			 */
			// 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);
		}
	}
}

事务注解支持的三剑客

  1. AnnotationTransactionAttributeSource
    ↓(解析注解)
  2. TransactionInterceptor
    ↓(执行事务逻辑)
  3. BeanFactoryTransactionAttributeSourceAdvisor
    ↓(组装切点+通知)

总结一下XML入口, 就是无论 xml 支持 还是注解支持都会构造 org.springframework.transaction.interceptor.TransactionInterceptor 这个核心 advice 事务拦截器

对于注解的入口

@EnableTransactionManagement
public class TXMain {

	@Transactional
	public static void main(String[] args) throws Exception {
		System.out.println("==========================================================");
		//ApplicationContext context = new ClassPathXmlApplicationContext("application-tx.xml");
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TXMain.class);
		BookService bookService = context.getBean("bookService", BookService.class);
		Book book = new Book();
		book.setName("30秒精通javascript,一分钟精通java");
		book.setCode(""+System.currentTimeMillis());
//		bookService.insertWithTransaction(book );
		bookService.insertWithNoTransaction(book);
		System.out.println("bookService = "+bookService);
		System.out.println("bookService getList = "+bookService.getList());
		System.out.println("==========================================================");
	}
}

@EnableTransactionManagement 注解导入了 TransactionManagementConfigurationSelector 默认选中的是 ProxyTransactionManagementConfiguration

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

	/**
	 * Returns {@link ProxyTransactionManagementConfiguration} or
	 * {@code AspectJ(Jta)TransactionManagementConfiguration} for {@code PROXY}
	 * and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},
	 * respectively.
	 */
	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
		return switch (adviceMode) {
		
			case PROXY -> new String[] {AutoProxyRegistrar.class.getName(),
					ProxyTransactionManagementConfiguration.class.getName()};
			case ASPECTJ -> new String[] {determineTransactionAspectClass()};
		};
	}

	private String determineTransactionAspectClass() {
		return (ClassUtils.isPresent("jakarta.transaction.Transactional", getClass().getClassLoader()) ?
				TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
				TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
	}

}

同样注解的三剑客

  1. AnnotationTransactionAttributeSource
    ↓(解析注解)
  2. TransactionInterceptor
    ↓(执行事务逻辑)
  3. BeanFactoryTransactionAttributeSourceAdvisor
    ↓(组装切点+通知)

org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration

/*
 * Copyright 2002-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.transaction.annotation;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.context.annotation.Role;
import org.springframework.transaction.config.TransactionManagementConfigUtils;
import org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor;
import org.springframework.transaction.interceptor.TransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionInterceptor;

/**
 * {@code @Configuration} class that registers the Spring infrastructure beans
 * necessary to enable proxy-based annotation-driven transaction management.
 *
 * @author Chris Beams
 * @author Sebastien Deleuze
 * @since 3.1
 * @see EnableTransactionManagement
 * @see TransactionManagementConfigurationSelector
 */
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@ImportRuntimeHints(TransactionRuntimeHints.class)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
			TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {

		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		advisor.setTransactionAttributeSource(transactionAttributeSource);
		advisor.setAdvice(transactionInterceptor);
		if (this.enableTx != null) {
			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		}
		return advisor;
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionAttributeSource transactionAttributeSource() {
		// Accept protected @Transactional methods on CGLIB proxies, as of 6.0.
		return new AnnotationTransactionAttributeSource(false);
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
		TransactionInterceptor interceptor = new TransactionInterceptor();
		interceptor.setTransactionAttributeSource(transactionAttributeSource);
		if (this.txManager != null) {
			interceptor.setTransactionManager(this.txManager);
		}
		return interceptor;
	}

}

Spring 声明式事务的入口点