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

推荐订阅源

The Last Watchdog
The Last Watchdog
K
Kaspersky official blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Spread Privacy
Spread Privacy
T
Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
MongoDB | Blog
MongoDB | Blog
V
Vulnerabilities – Threatpost
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Help Net Security
Help Net Security
Microsoft Azure Blog
Microsoft Azure Blog
GbyAI
GbyAI
小众软件
小众软件
Cloudbric
Cloudbric
The Hacker News
The Hacker News
阮一峰的网络日志
阮一峰的网络日志
Vercel News
Vercel News
人人都是产品经理
人人都是产品经理
Forbes - Security
Forbes - Security
Martin Fowler
Martin Fowler
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
AWS News Blog
AWS News Blog
Stack Overflow Blog
Stack Overflow Blog
N
News | PayPal Newsroom
P
Privacy & Cybersecurity Law Blog
TaoSecurity Blog
TaoSecurity Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园_首页
A
Arctic Wolf
www.infosecurity-magazine.com
www.infosecurity-magazine.com
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Scott Helme
Scott Helme
T
Tor Project blog
S
Secure Thoughts
Know Your Adversary
Know Your Adversary
P
Proofpoint News Feed
M
MIT News - Artificial intelligence
博客园 - 司徒正美
T
Threat Research - Cisco Blogs
C
Cyber Attacks, Cyber Crime and Cyber Security
Schneier on Security
Schneier on Security
B
Blog RSS Feed
AI
AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Attack and Defense Labs
Attack and Defense Labs
Webroot Blog
Webroot Blog
Google DeepMind News
Google DeepMind News
Project Zero
Project Zero
Hacker News: Ask HN
Hacker News: Ask HN

博客园 - daidaidaiyu

ZooKeepper 一文入门 ThingsBoard 规则链系统源码分析和自定义定时器 嵌入式开发入门知识 一文入门和实践Kafka 一文学习入门 ThingsBoard 开源物联网平台 Claude Code 使用一则 JMS, ActiveMQ 学习一则 Nacos实例一则及其源码环境搭建 一文学习 工作流开发 BPMN、 Flowable 一文学习 Spring 声明式事务源码全流程总结 Spring IOC 源码学习 事务相关的 BeanDefinition 解析过程 (XML) GIS 核心知识 Spring IOC 源码学习 声明式事务的入口点 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-22 · via 博客园 - daidaidaiyu

事务增强相关的对象创建

internalAutoProxyCreator 对象

首先是 internalAutoProxyCreator 它是负责创建AOP对象 它本身是BPP, 它会在 registerBeanPostProcessors(beanFactory); 过程中被实例化
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)


	/**
	 *  in short:
	 *  1. 拿到所有实现 BeanPostProcessor 的 bean, 然后进行分类存起来
	 *  这有一点, Spring 对 BeanDefinition 分成三种角色:
	 *  	1. 用户定义的 Bean (ROLE_APPLICATION)
	 *      2. 较复杂的 (ROLE_SUPPORT) 较复杂的? 通常是一个外部配置
	 *      3. Spring 内置的(ROLE_INFRASTRUCTURE)
	 *  2. 如果实现了 BeanPostProcessor 则会实例化这个bean, 但注意这里只是注册,并不会调用BeanPostProcessor的相关方法
	 *
	 *  另外 BeanPostProcessor 粗粒度太大, Spring 还细分一些子接口:
	 *  - SmartInstantiationAwareBeanPostProcessor 它提供了更高级的Bean实例化控制方法。主要作用在于允许对Bean的实例化过程进行更精细的控制和定制。
	 *  - MergedBeanDefinitionPostProcessor 在合并Bean定义(MergedBeanDefinition)之后但在实例化Bean之前,允许对合并后的Bean定义进行修改、调整或附加元数据。
	 *  - DestructionAwareBeanPostProcessor 它允许在Bean被销毁之前(例如,容器关闭或特定作用域的Bean销毁)执行一些操作。
	 */
	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		// WARNING: Although it may appear that the body of this method can be easily
		// refactored to avoid the use of multiple loops and multiple lists, the use
		// of multiple lists and multiple passes over the names of processors is
		// intentional. We must ensure that we honor the contracts for PriorityOrdered
		// and Ordered processors. Specifically, we must NOT cause processors to be
		// instantiated (via getBean() invocations) or registered in the ApplicationContext
		// in the wrong order.
		//
		// Before submitting a pull request (PR) to change this method, please review the
		// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
		// to ensure that your proposal does not result in a breaking change:
		// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
		/**
		 * 拿到所有实现 BeanPostProcessor 的 bean名称
		 */
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		/**
		 * 计算 BeanPostProcessor(BPP) 的总数.
		 * +1 是什么操作? 原因是: 下一行,又加了一个 BeanPostProcessorChecker
		 */
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		// BeanPostProcessorChecker 这个BeanPostProcessor, 没啥实际作用, 就是记录了一些日志;
		beanFactory.addBeanPostProcessor(
				new BeanPostProcessorChecker(beanFactory, postProcessorNames, beanProcessorTargetCount));
		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		/**
		 * 对 BeanPostProcessor 进行分类存起来,  再调用, 每个集合分别是
		 * 1. priorityOrderedPostProcessors //有实现(PriorityOrdered)排序接口的
		 * 2. internalPostProcessors //Spring内部的bean, 见: Spring将bean分为三种角色
		 * 3. orderedPostProcessorNames //实现 Ordered 接口
		 * 4. nonOrderedPostProcessorNames //没有指定顺序, 无序的
		 */
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				/**
				 * 注意, 若 bean 实现了 PriorityOrdered 接口, 则会优先实例化它;
				 */
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, register the BeanPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		/**
		 * 注册所有常规BeanPostProcessors
		 * 这里 getBean 实例化bean !;
		 */
		// Now, register all regular(常规) BeanPostProcessors.
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		/**
		 * 最后, 注册所有 内置 BeanPostProcessor
		 */
		// Finally, re-register all internal BeanPostProcessors.
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		//最后再放一个 ApplicationListenerDetector 让它在最后 (不是重点, 见名应该是事件相关的)
		// Re-register post-processor for detecting inner beans as ApplicationListeners,
		// moving it to the end of the processor chain (for picking up proxies etc).
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

DefaultBeanFactoryPointcutAdvisor 和 AspectJExpressionPointcut 对象

internalAutoProxyCreator 会在 postProcessBeforeInstantiation 回调中的org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#shouldSkip判断时实例化所有的 Advisor

在实例化 Advisor 填充属性时也会把 AspectJExpressionPointcut 也实例化

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation

@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {

		/**
		 * 常规情况下:  这里只是检查下缓存和标记缓存
		 * 对于真正的AOP代理创建见:
		 * {@link AbstractAutoProxyCreator#postProcessAfterInitialization(java.lang.Object, java.lang.String)}
		 */
		Object cacheKey = getCacheKey(beanClass, beanName);
		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {

			/**
			 *
			 *  不管需不需要, 只要处理过了就缓存
			 * 	advisedBeans 这个变量, 缓存所有处理过的 bean名称;
			 * 	value 为 boolean值, 如果为false 则不处理
			 */
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			/**
			 * isInfrastructureClass 是否是基础功能类,即 AOP相关的几个类:
			 * Advice.class Pointcut.class Advisor.class AopInfrastructureBean.class 都为true
			 *
			 * shouldSkip 判断时, 拿到容器的所有 Advisor, 并且实例化 `getBean()` 这个 Advisor
			 */
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
			if (StringUtils.hasLength(beanName)) {
				this.targetSourcedBeans.add(beanName);
			}
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		return null;
	}

TransactionInterceptort 对象

是在 internalAutoProxyCreator 遇到需要增强代理的对象时, 这里是 bookService 去 getAdvicesAndAdvisorsForBean 查找到其匹配 bookService 的 Advisor
这里若 Advisor 匹配, 会调用 getAdvice 获取其切面, 此时切面不存在则会实例化它

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}
		/**
		 * 拿到所有匹配织入当前bean的 所有通知器(Advisor)
		 * 做了三件事, 见: {@link org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean(java.lang.Class, java.lang.String, org.springframework.aop.TargetSource)}
		 * 1. 往返回 `AspectJXXXAdvice`列表数组`0`索引 插入一个{@link org.springframework.aop.interceptor.ExposeInvocationInterceptor} 实例
		 * 方便传递参数用的
		 *
		 * 2. 怎么匹配(Advisor)?
		 * Advisor中的 `AspectJExpressionPointcut` 是实现 {@link ClassFilter} 和 {@link org.springframework.aop.MethodMatcher} 接口
		 * 一个进行类匹配, 一个进行方法匹配. Advisor 匹配会调用 getAdvice 获取其切面, 此时切面不存在则会实例化
		 *
		 * 3.  排序, 基于 `有向无环` 图进行排序; 可能匹配到多个切面(aspect)
		 *
		 */
		// Create proxy if we have advice.
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			/**
			 *{@link org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#advisedBeans}
			 * 这个变量缓存所有处理过的 bean名称, value 为 boolean值, 如果为false 则不处理
			 */
			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;
	}

汇总图

Spring TX