Devin's Blogs

个人点滴记录

加载文件方式

xml 配置文件

类路径获取配置文件

ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring.xml");

文件系统路径获取配置文件

ApplicationContext applicationContext = new FileSystemXmlApplicationContext("/home/usr/learn-spring-framework5.2/spring-demo/src/main/resources/spring.xml");

Java 配置类

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringDemoConfig.class);

Spring 核心加载方法

AbstractApplicationContext#refresh()方法是 Spring 容器启动过程中的核心方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* 加载或刷新配置的持久化表示,可能是XML文件、属性文件或关系数据库。
* 由于这是一个启动方法,如果它调用失败,它应该销毁已创建的单例,以避免悬空资源。换句话说,在调用该方法之后,要么全部实例化,要么都不实例化。
* @throws BeansException
* @throws IllegalStateException
*/
@Override
public void refresh() throws BeansException, IllegalStateException {
/*
* 使用对象锁 startUpShutdownMonitor 进行同步控制:
* 1、避免了多线程同时刷新 spring 配置,只对不能并发的代码块进行加锁, 提高了整体代码运行的效率;
* 2、refresh() 方法和 close() 方法都使用了 startUpShutdownMonitor 对象锁加锁,
* 这就保证了在调用 refresh() 方法的时候无法调用 close() 方法,避免了冲突;
**/
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 容器刷新前的准备工作
/*
* 1. 设置容器的启动时间
* 2. 设置容器开启和关闭标志位
* 3. 获取 Environment 对象, 并加载当前系统的属性到 Environment 对象中
* 4. 准备监听器和事件的集合对象, 默认为空集合
*/
prepareRefresh();

// Tell the subclass to refresh the internal bean factory.
// 创建容器对象:DefaultListableBeanFactory
// 解析xml配置文件的属性值封装到BeanDefinition对象中, 并注册到当前工厂中
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
// beanFactory的准备工作,对各种属性进行填充(为容器注册必要的系统级别的Bean)
prepareBeanFactory(beanFactory);

try {
// Allows post-processing of the bean factory in context subclasses.
// 允许容器的子类去注册 postProcessor, 钩子方法
// 子类覆盖方法做额外的处理, 可参考 web 中的代码
postProcessBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.
// 调用容器中的各种 beanFactory 的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
// 向容器注册 bean 的后置处理器,这里只是注册功能,真正调用的是 getBean 方法
registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.
// 为上下文初始化message源,即不同语言的消息体 (国际化处理)
initMessageSource();

// Initialize event multicaster for this context.
// 初始化事件监听多路广播器
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
// 在单例 Bean 初始化之前预留子类初始化其他特殊 Bean 的口子, 钩子方法
onRefresh();

// Check for listener beans and register them.
// 在所有注册的 bean 中查找 listener bean, 注册到消息广播器中
registerListeners();

// Instantiate all remaining (non-lazy-init) singletons.
// 实例化所有剩余的(非懒加载)单例
finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.
// 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,
// 同时发出 ContextRefreshEvent 事件通知别人
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}

// Destroy already created singletons to avoid dangling resources.
// 销毁已经创建的Bean
destroyBeans();

// Reset 'active' flag.
// 重置容器激活标签
cancelRefresh(ex);

// Propagate exception to caller.
throw ex;
}

finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
// 重置 Spring 内核中的公用缓存
resetCommonCaches();
}
}
}

简介

本系列笔记从简单的 demo 出发,来阅读 Spring 的源码。

目录

Spring源码之容器加载

Spring 源码之核心加载方法(1)

Spring 源码之核心加载方法(2) BeanFactory 创建

Spring 源码之核心加载方法(2) 配置文件加载

Spring 源码之核心加载方法(2) 配置文件加载2

Spring 源码之核心加载方法(3) beanFactory 的准备工作

Spring 源码之核心加载方法(4) 容器钩子方法

Spring 源码之核心加载方法(5) 执行 BeanFactoryPostProcessor

Spring 源码之核心加载方法(6) 注册 BeanPostProcessor

Spring 源码之核心加载方法(7) 初始化消息资源

Spring 源码之核心加载方法(8-10) 初始化和注册广播器

Spring 源码之核心加载方法(11) 实例化对象

Spring 源码之核心加载方法(12) 实例化对象

Spring 源码之核心加载方法(13) finishRefresh

Spring 源码之核心加载方法(14) 完成后清理

Spring 源码之核心加载方法 常用扩展点接口

参考链接

源码注释

xml 配置

1
2
3
4
5
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource"/>
</bean>
<!-- 启用声明式事务 -->
<tx:annotation-driven />

xml 解析

TxNamespaceHandler

定位: org.springframework.transaction.config.TxNamespaceHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
// 如果事务注解没有配置事务管理器引用, 使用 Spring 容器中的 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() {
// 注册不同的 xml 文件标签解析器
registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
}

AnnotationDrivenBeanDefinitionParser

定位: org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 解析 annotation-driven 标签
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("javax.transaction.Transactional", getClass().getClassLoader())) {
registerJtaTransactionAspect(element, parserContext);
}
} else {
// mode="proxy" // 默认配置
AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
}
return null;
}

AopAutoProxyConfigurer

定位: org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer

作用: 依据 AnnotationTransactionAttributeSourceTransactionInterceptor 元信息构造出 BeanFactoryTransactionAttributeSourceAdvisor 的元信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
private static class AopAutoProxyConfigurer {
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
// aop 注册
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.
// 创建 TransactionAttributeSource 的 bean
RootBeanDefinition sourceDef = new RootBeanDefinition(
"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
sourceDef.setSource(eleSource);
sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 注册 bean,并使用Spring中的定义规则生成 beanName
String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

// Create the TransactionInterceptor definition.
// 创建 TransactionInterceptor 的 bean
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.
// 创建 TransactionAttributeSourceAdvisor 的 bean
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
advisorDef.setSource(eleSource);
advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 将 sourceName 的 bean 注入 advisorDef 的 transactionAttributeSource 属性中
advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
// 将 interceptorName 的 bean 注入 advisorDef 的 adviceBeanName 属性中
advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
// 如果配置了 order 属性,则加入到 bean 中
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);
}
}
}

TransactionAttributeSourceAdvisor

定位: org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor

将 pointcut 和 advice 封装成 Advisor 对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class TransactionAttributeSourceAdvisor extends AbstractPointcutAdvisor {
@Nullable
private TransactionInterceptor transactionInterceptor;
// pointcut 属性赋值
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
@Nullable
protected TransactionAttributeSource getTransactionAttributeSource() {
return (transactionInterceptor != null ? transactionInterceptor.getTransactionAttributeSource() : null);
}
};
@Override
public Advice getAdvice() {
Assert.state(this.transactionInterceptor != null, "No TransactionInterceptor set");
return this.transactionInterceptor;
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
}

pointcut 匹配规则

定位:org.springframework.transaction.interceptor.TransactionAttributeSourcePointcut.TransactionAttributeSourceClassFilter#matches

类匹配

1
2
3
4
5
6
7
8
9
10
11
12
private class TransactionAttributeSourceClassFilter implements ClassFilter {
@Override
public boolean matches(Class<?> clazz) {
if (TransactionalProxy.class.isAssignableFrom(clazz) ||
TransactionManager.class.isAssignableFrom(clazz) ||
PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) {
return false;
}
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.isCandidateClass(clazz));
}
}

定位: org.springframework.transaction.interceptor.TransactionAttributeSourcePointcut#matches

方法匹配

1
2
3
4
5
6
7
8
9
10
@Override
public boolean matches(Method method, Class<?> targetClass) {
/**
* 获取我们@EnableTransactionManagement注解为我们容器中导入的ProxyTransactionManagementConfiguration
* 配置类中的TransactionAttributeSource对象
*/
TransactionAttributeSource tas = getTransactionAttributeSource();
// 若事务属性原为null或者解析出来的事务注解属性不为空,表示方法匹配
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

advice 通知

TransactionInterceptor

此类实现了 MethodInterceptor 接口,继承了 TransactionAspectSupport

定位: org.springframework.transaction.interceptor.TransactionInterceptor#invoke

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
@Nullable
public Object invoke(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属性
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

// Adapt to TransactionAspectSupport's invokeWithinTransaction...
/**
* 以事务的方式调用目标方法
* 在这埋了一个钩子函数 用来回调目标方法的
*/
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}

TransactionAspectSupport

invokeWithinTransaction

定位: org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

事务开启, 回滚和提交

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
// 获取我们的事务属性源对象
TransactionAttributeSource tas = getTransactionAttributeSource();
// 通过事务属性源对象获取到当前方法的事务属性信息
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
// 获取我们配置的事务管理器对象
final TransactionManager tm = determineTransactionManager(txAttr);

if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
throw new TransactionUsageException(
"Unsupported annotated transaction on suspending function detected: " + method +
". Use TransactionalOperator.transactional extensions instead.");
}
ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(method.getReturnType());
if (adapter == null) {
throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
method.getReturnType());
}
return new ReactiveTransactionSupport(adapter);
});
return txSupport.invokeWithinTransaction(
method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
}

PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
// 获取连接点的唯一标识 类名+方法名
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

// 声明式事务处理
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
// 创建TransactionInfo
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);

Object retVal;
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);
}

if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
TransactionStatus status = txInfo.getTransactionStatus();

if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}

//成功后提交,会进行资源储量,连接释放,恢复挂起事务等操作
commitTransactionAfterReturning(txInfo);
return retVal;
}

else {
// 编程式事务处理
Object result;
final ThrowableHolder throwableHolder = new ThrowableHolder();

// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
try {
result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
try {
Object retVal = invocation.proceedWithInvocation();
if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
return retVal;
}
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.
throwableHolder.throwable = ex;
return null;
}
}
finally {
cleanupTransactionInfo(txInfo);
}
});
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
catch (TransactionSystemException ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
ex2.initApplicationException(throwableHolder.throwable);
}
throw ex2;
}
catch (Throwable ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
}
throw ex2;
}

// Check result state: It might indicate a Throwable to rethrow.
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
}
return result;
}
}

createTransactionIfNecessary

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {

// If no name specified, apply method identification as transaction name.
// 如果没有名称指定则使用方法唯一标识,并使用 DelegatingTransactionAttribute 封装 txAttr
if (txAttr != null && txAttr.getName() == null) {
txAttr = new DelegatingTransactionAttribute(txAttr) {
@Override
public String getName() {
return joinpointIdentification;
}
};
}

TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
// 获取 TransactionStatus 事务状态信息
status = tm.getTransaction(txAttr);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
"] because no transaction manager has been configured");
}
}
}
// 根据指定的属性与status准备一个TransactionInfo,
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}

prepareTransactionInfo

事务的准备工作, 开启事务/设置事务状态/事务信息绑定到当前线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, String joinpointIdentification,
@Nullable TransactionStatus status) {

// 创建事务信息
TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
if (txAttr != null) {
// We need a transaction for this method...
if (logger.isTraceEnabled()) {
logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
// The transaction manager will flag an error if an incompatible tx already exists.
// 设置新事务状态
txInfo.newTransactionStatus(status);
}
else {
// The TransactionInfo.hasTransaction() method will return false. We created it only
// to preserve the integrity of the ThreadLocal stack maintained in this class.
if (logger.isTraceEnabled()) {
logger.trace("No need to create transaction for [" + joinpointIdentification +
"]: This method is not transactional.");
}
}

// We always bind the TransactionInfo to the thread, even if we didn't create
// a new transaction here. This guarantees that the TransactionInfo stack
// will be managed correctly even if no transaction was created by this aspect.
// 事务信息绑定到当前线程
txInfo.bindToThread();
return txInfo;
}

DataSourceTransactionManager

jdbc 数据源是事务管理器,继承自 AbstractPlatformTransactionManager

doBegin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
protected void doBegin(Object transaction, TransactionDefinition definition) {
// 强制转化事务对象
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
Connection con = null;

try {
// 判断事务对象没有数据库连接持有器
if (!txObject.hasConnectionHolder() ||
txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
// 通过数据源获取一个数据库连接对象
Connection newCon = obtainDataSource().getConnection();
if (logger.isDebugEnabled()) {
logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
}
// 把我们的数据库连接包装成一个ConnectionHolder 对象 然后设置到我们的 txObject 对象中去
txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}

// 标记当前的连接是一个同步事务
txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
con = txObject.getConnectionHolder().getConnection();

// 数据连接的只读标识,设置当前的事务隔离级别
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
// 事务对象设置先前隔离级别
txObject.setPreviousIsolationLevel(previousIsolationLevel);
// 事务对象设置是否只读
txObject.setReadOnly(definition.isReadOnly());

// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
// so we don't want to do it unnecessarily (for example if we've explicitly
// configured the connection pool to set it already).
// 关闭自动提交
if (con.getAutoCommit()) {
//设置需要恢复自动提交
txObject.setMustRestoreAutoCommit(true);
if (logger.isDebugEnabled()) {
logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
}
// 关闭自动提交
con.setAutoCommit(false);
}

// 判断事务是否需要设置为只读事务
prepareTransactionalConnection(con, definition);
// 标记激活事务
txObject.getConnectionHolder().setTransactionActive(true);

// 设置事务超时时间
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
}

// Bind the connection holder to the thread.
// 绑定我们的数据源和连接到我们的同步管理器上,把数据源作为key,数据库连接作为value 设置到线程变量中
if (txObject.isNewConnectionHolder()) {
// 将当前获取到的连接绑定到当前线程
TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
}
}

catch (Throwable ex) {
if (txObject.isNewConnectionHolder()) {
// 释放数据库连接
DataSourceUtils.releaseConnection(con, obtainDataSource());
txObject.setConnectionHolder(null, false);
}
throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
}
}
protected void prepareTransactionalConnection(Connection con, TransactionDefinition definition)
throws SQLException {
if (isEnforceReadOnly() && definition.isReadOnly()) {
try (Statement stmt = con.createStatement()) {
// 设置当前会话事务只读
stmt.executeUpdate("SET TRANSACTION READ ONLY");
}
}
}

@Override
protected Object doGetTransaction() {
// 创建一个数据源事务对象
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
// 是否允许当前事务设置保持点
txObject.setSavepointAllowed(isNestedTransactionAllowed());
/**
* TransactionSynchronizationManager 事务同步管理器对象(该类中都是局部线程变量)
* 用来保存当前事务的信息,我们第一次从这里去线程变量中获取 事务连接持有器对象 通过数据源为 key 去获取
* 由于第一次进来开始事务 我们的事务同步管理器中没有被存放.所以此时获取出来的 conHolder 为 null
*/
ConnectionHolder conHolder =
(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
txObject.setConnectionHolder(conHolder, false);
// 返回事务对象
return txObject;
}

doCleanupAfterCompletion

此方法做清除连接相关操作,比如重置自动提交啊,只读属性啊,解绑数据源啊,释放连接啊,清除链接持有器属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Override
protected void doCleanupAfterCompletion(Object transaction) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;

// Remove the connection holder from the thread, if exposed.
if (txObject.isNewConnectionHolder()) {
// 将数据库连接从当前线程中解除绑定
TransactionSynchronizationManager.unbindResource(obtainDataSource());
}

// Reset connection.
// 释放连接
Connection con = txObject.getConnectionHolder().getConnection();
try {
if (txObject.isMustRestoreAutoCommit()) {
// 恢复数据库连接的自动提交属性
con.setAutoCommit(true);
}
// 重置数据库连接
DataSourceUtils.resetConnectionAfterTransaction(
con, txObject.getPreviousIsolationLevel(), txObject.isReadOnly());
}
catch (Throwable ex) {
logger.debug("Could not reset JDBC Connection after transaction", ex);
}

if (txObject.isNewConnectionHolder()) {
if (logger.isDebugEnabled()) {
logger.debug("Releasing JDBC Connection [" + con + "] after transaction");
}
// 如果当前事务是独立的新创建的事务则在事务完成时释放数据库连接
DataSourceUtils.releaseConnection(con, this.dataSource);
}

// 连接持有器属性清除
txObject.getConnectionHolder().clear();
}

AbstractPlatformTransactionManager

getTransaction

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException {

// Use defaults if no transaction definition given.
// 如果没有事务定义信息则使用默认的事务管理器定义信息
TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());

// 获取事务
Object transaction = doGetTransaction();
boolean debugEnabled = logger.isDebugEnabled();

// 判断当前线程是否存在事务,判断依据为当前线程记录的连接不为空且连接中的 transactionActive 属性不为空
if (isExistingTransaction(transaction)) {
// Existing transaction found -> check propagation behavior to find out how to behave.
// 当前线程已经存在事务
return handleExistingTransaction(def, transaction, debugEnabled);
}

// Check definition settings for new transaction.
// 事务超时设置验证
if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
}

// No existing transaction found -> check propagation behavior to find out how to proceed.
// 如果当前线程不存在事务,但是 PropagationBehavior 却被声明为 PROPAGATION_MANDATORY 抛出异常
if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
// PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW,PROPAGATION_NESTED 都需要新建事务
else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
// 没有当前事务的话,REQUIRED,REQUIRES_NEW,NESTED 挂起的是空事务,然后创建一个新事务
SuspendedResourcesHolder suspendedResources = suspend(null);
if (debugEnabled) {
logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
}
try {
return startTransaction(def, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error ex) {
// 恢复挂起的事务
resume(null, suspendedResources);
throw ex;
}
}
else {
// Create "empty" transaction: no actual transaction, but potentially synchronization.
// 创建一个空的事务
if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
logger.warn("Custom isolation level specified but no actual transaction initiated; " +
"isolation level will effectively be ignored: " + def);
}
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
}
}
// 开启新事务
private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {

// 是否需要新同步
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
// 创建新的事务
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
// 开启事务和连接
doBegin(transaction, definition);
// 对于新同步事务,设置事务信息到当前线程变量
prepareSynchronization(status, definition);
return status;
}

handleExistingTransaction

在开始事务时,如果当前线程是否存在事务,则进行嵌套事务的处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {

/**
* 判断当前的事务行为是不是PROPAGATION_NEVER的
* 表示为不支持事务,但是当前又存在一个事务,所以抛出异常
*/
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
}

/**
* 判断当前的事务属性不支持事务,PROPAGATION_NOT_SUPPORTED,所以需要先挂起已经存在的事务
*/
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
if (debugEnabled) {
logger.debug("Suspending current transaction");
}
// 挂起当前事务
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
// 创建一个新的非事务状态(保存了上一个存在事务状态的属性)
return prepareTransactionStatus(
definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}

/**
* 当前的事务属性状态是PROPAGATION_REQUIRES_NEW表示需要新开启一个事务状态
*/
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
if (debugEnabled) {
logger.debug("Suspending current transaction, creating new transaction with name [" +
definition.getName() + "]");
}
// 挂起当前事务并返回挂起的资源持有器
SuspendedResourcesHolder suspendedResources = suspend(transaction);
try {
// 创建一个新的非事务状态(保存了上一个存在事务状态的属性)
return startTransaction(definition, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
}

// 嵌套事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
// 不允许就报异常
if (!isNestedTransactionAllowed()) {
throw new NestedTransactionNotSupportedException(
"Transaction manager does not allow nested transactions by default - " +
"specify 'nestedTransactionAllowed' property with value 'true'");
}
if (debugEnabled) {
logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
}
// 嵌套事务的处理
if (useSavepointForNestedTransaction()) {
// Create savepoint within existing Spring-managed transaction,
// through the SavepointManager API implemented by TransactionStatus.
// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
// 如果没有可以使用保存点的方式控制事务回滚,那么在嵌入式事务的建立初始简历保存点
DefaultTransactionStatus status =
prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
// 为事务设置一个回退点
status.createAndHoldSavepoint();
return status;
}
else {
// Nested transaction through nested begin and commit/rollback calls.
// Usually only for JTA: Spring synchronization might get activated here
// in case of a pre-existing JTA transaction.
// 有些情况是不能使用保存点操作
return startTransaction(definition, transaction, debugEnabled, null);
}
}

// Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
if (debugEnabled) {
logger.debug("Participating in existing transaction");
}
if (isValidateExistingTransaction()) {
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
Constants isoConstants = DefaultTransactionDefinition.constants;
throw new IllegalTransactionStateException("Participating transaction with definition [" +
definition + "] specifies isolation level which is incompatible with existing transaction: " +
(currentIsolationLevel != null ?
isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
"(unknown)"));
}
}
if (!definition.isReadOnly()) {
if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
throw new IllegalTransactionStateException("Participating transaction with definition [" +
definition + "] is not marked as read-only but existing transaction is");
}
}
}
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}

rollback

事务管理器根据事务状态来处理回滚

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
public final void rollback(TransactionStatus status) throws TransactionException {
if (status.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}

DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
processRollback(defStatus, false);
}
/**
* unexpected 一般是 false,除非是设置 rollback-only=true,才是true,表示是全局的回滚标记。首先会进行回滚前回调,
* 然后判断是否设置了保存点,比如 NESTED 会设置,要先回滚到保存点。如果状态是新的事务,那就进行回滚,如果不是新的,就设置一个回滚标记,
* 内部是设置连接持有器回滚标记。然后回滚完成回调,根据事务状态信息,完成后数据清除,和线程的私有资源解绑,
* 重置连接自动提交,隔离级别,是否只读,释放连接,恢复挂起事务等
*/
private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
try {
// 意外的回滚
boolean unexpectedRollback = unexpected;

try {
// 回滚完成前回调
triggerBeforeCompletion(status);
// 有保存点回滚到保存点
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Rolling back transaction to savepoint");
}
status.rollbackToHeldSavepoint();
}
// 当前状态是一个新事务
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction rollback");
}
// 进行回滚
doRollback(status);
}
else {
// Participating in larger transaction
if (status.hasTransaction()) {
if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
if (status.isDebug()) {
logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
}
//设置连接要回滚标记,也就是全局回滚
doSetRollbackOnly(status);
}
else {
if (status.isDebug()) {
logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
}
}
}
else {
logger.debug("Should roll back transaction but cannot - no transaction available");
}
// Unexpected rollback only matters here if we're asked to fail early
if (!isFailEarlyOnGlobalRollbackOnly()) {
unexpectedRollback = false;
}
}
}
catch (RuntimeException | Error ex) {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw ex;
}

// 回滚完成后回调
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);

// Raise UnexpectedRollbackException if we had a global rollback-only marker
if (unexpectedRollback) {
throw new UnexpectedRollbackException(
"Transaction rolled back because it has been marked as rollback-only");
}
}
finally {
// 根据事务状态信息,完成后数据清除,和线程的私有资源解绑,重置连接自动提交,隔离级别,是否只读,释放连接,恢复挂起事务等
cleanupAfterCompletion(status);
}
}

commit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
public final void commit(TransactionStatus status) throws TransactionException {
if (status.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
// 如果在事务链中已经被标记回滚,那么不会尝试提交事务,直接回滚
if (defStatus.isLocalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Transactional code has requested rollback");
}
// 不可预期的回滚
processRollback(defStatus, false);
return;
}

// 设置了全局回滚
if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
}
// 可预期的回滚,可能会报异常
processRollback(defStatus, true);
return;
}

// 处理事务提交
processCommit(defStatus);
}

/**
* 处理提交,先处理保存点,然后处理新事务,如果不是新事务不会真正提交,要等外层是新事务的才提交,
* 最后根据条件执行数据清除,线程的私有资源解绑,重置连接自动提交,隔离级别,是否只读,释放连接,恢复挂起事务等
*/
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
try {
boolean beforeCompletionInvoked = false;

try {
boolean unexpectedRollback = false;
// 预留
prepareForCommit(status);
// 添加的 TransactionSynchronization 中的对应方法的调用
triggerBeforeCommit(status);
// 提交完成前回调
triggerBeforeCompletion(status);
beforeCompletionInvoked = true;

// 有保存点
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Releasing transaction savepoint");
}
//是否有全局回滚标记
unexpectedRollback = status.isGlobalRollbackOnly();
// 如果存在保存点则清除保存点信息
status.releaseHeldSavepoint();
}
// 当前状态是新事务
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction commit");
}
unexpectedRollback = status.isGlobalRollbackOnly();
// 如果是独立的事务则直接提交
doCommit(status);
}
else if (isFailEarlyOnGlobalRollbackOnly()) {
unexpectedRollback = status.isGlobalRollbackOnly();
}

// Throw UnexpectedRollbackException if we have a global rollback-only
// marker but still didn't get a corresponding exception from commit.
// 有全局回滚标记就报异常
if (unexpectedRollback) {
throw new UnexpectedRollbackException(
"Transaction silently rolled back because it has been marked as rollback-only");
}
}
catch (UnexpectedRollbackException ex) {
// can only be caused by doCommit
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
throw ex;
}
catch (TransactionException ex) {
// can only be caused by doCommit
if (isRollbackOnCommitFailure()) {
doRollbackOnCommitException(status, ex);
}
else {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
}
throw ex;
}
catch (RuntimeException | Error ex) {
if (!beforeCompletionInvoked) {
triggerBeforeCompletion(status);
}
// 提交过程中出现异常则回滚
doRollbackOnCommitException(status, ex);
throw ex;
}

// Trigger afterCommit callbacks, with an exception thrown there
// propagated to callers but the transaction still considered as committed.
try {
// 提交后回调
triggerAfterCommit(status);
}
finally {
// 提交后清除线程私有同步状态
triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
}

}
finally {
//根据条件,完成后数据清除,和线程的私有资源解绑,重置连接自动提交,隔离级别,是否只读,释放连接,恢复挂起事务等
cleanupAfterCompletion(status);
}
}

介绍常用的 Advice

img

AspectJMethodBeforeAdvice, AspectJAfterReturningAdvice 没有实现 MethodInterceptor 接口, 在构造调用链时会通过 MethodBeforeAdviceAdapter, AfterReturningAdviceAdapter 这两个适配器转换成对应的接口,通过调用 MethodInterceptor#invoke 方法来实现对各个方法的处理

AspectJMethodBeforeAdvice

定位: org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor#invoke

1
2
3
4
5
6
7
8
// invoke 方法是拦截器的回调方法,会在代理对应的方法被调用时触发回调
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 执行前置通知的方法
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
// 执行下一个通知/拦截器,如果该拦截器是最后一个了,将会调用目标方法
return mi.proceed();
}

定位: org.springframework.aop.aspectj.AspectJMethodBeforeAdvice#before

1
2
3
4
public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
// 这里传进来的目标对象、目标参数、目标方法都没有用到
invokeAdviceMethod(getJoinPointMatch(), null, null);
}

AspectJAfterReturningAdvice

定位: org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor

1
2
3
4
5
6
7
public Object invoke(MethodInvocation mi) throws Throwable {
// 执行下一个通知/拦截器
Object retVal = mi.proceed();
// 返回通知方法
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}

定位: org.springframework.aop.aspectj.AspectJAfterReturningAdvice#afterReturning

1
2
3
4
5
public void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable {
if (shouldInvokeOnReturnValueOf(method, returnValue)) {
invokeAdviceMethod(getJoinPointMatch(), returnValue, null);
}
}

AspectJAfterThrowingAdvice

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public Object invoke(MethodInvocation mi) throws Throwable {
try {
// 执行下一个通知/拦截器 methodInvocation
return mi.proceed();
}
catch (Throwable ex) {
// 抛出异常
if (shouldInvokeOnThrowing(ex)) {
// 执行异常通知
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}

AspectJAfterAdvice

1
2
3
4
5
6
7
8
9
10
11
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
// 执行下一个通知/拦截器,如果该拦截器是最后一个了,将会调用目标方法
return mi.proceed();
}
finally {
// 执行后置通知的方法
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}

AspectJAroundAdvice

1
2
3
4
5
6
7
8
9
10
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
JoinPointMatch jpm = getJoinPointMatch(pmi);
return invokeAdviceMethod(pjp, jpm, null, null);
}

AbstractAspectJAdvice

invokeAdviceMethod

定位: org.springframework.aop.aspectj.AbstractAspectJAdvice#invokeAdviceMethod

调用 advice 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
protected Object invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch,
@Nullable Object returnValue, @Nullable Throwable t) throws Throwable {

return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));
}
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;
// 判断通知方法是否有参数
if (this.aspectJAdviceMethod.getParameterCount() == 0) {
actualArgs = null;
}
try {
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
// TODO AopUtils.invokeJoinpointUsingReflection
// 反射调用通知方法
// this.aspectInstanceFactory.getAspectInstance() 获取的是切面的实例
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("Mismatch on arguments to advice method [" +
this.aspectJAdviceMethod + "]; pointcut expression [" +
this.pointcut.getPointcutExpression() + "]", ex);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}

getJoinPointMatch

定位: org.springframework.aop.aspectj.AbstractAspectJAdvice#getJoinPointMatch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
protected JoinPointMatch getJoinPointMatch() {
// 这里是怎么获取到 MethodInvocation 的对象的呢?
// 我们在获取 Advisor 的时候,调用过方法 org.springframework.aop.aspectj.AspectJProxyUtils#makeAdvisorChainAspectJCapableIfNecessary
// 在这个方法中会有这样的一段代码, 如果存在 AspectJAdvice, 则将 ExposeInvocationInterceptor.ADVISOR 放到 Advisor 链的第一个
// 这样我们就不难理解了,在调用 ReflectiveMethodInvocation#proceed 的时候第一个调用的 MethodInterceptor 是 ExposeInvocationInterceptor
// 会将 MethodInvocation 放到线程变量中
MethodInvocation mi = ExposeInvocationInterceptor.currentInvocation();
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
// 这里主要是获取 JoinPointMatch
return getJoinPointMatch((ProxyMethodInvocation) mi);
}
protected JoinPointMatch getJoinPointMatch(ProxyMethodInvocation pmi) {
String expression = this.pointcut.getExpression();
return (expression != null ? (JoinPointMatch) pmi.getUserAttribute(expression) : null);
}

ProxyFactory

ProxyFactory#getProxy

定位: org.springframework.aop.framework.ProxyFactory#getProxy

1
2
3
4
public Object getProxy(@Nullable ClassLoader classLoader) {  
// createAopProxy() 用来创建我们的代理工厂
return createAopProxy().getProxy(classLoader);
}

createAopProxy

定位: org.springframework.aop.framework.ProxyCreatorSupport#createAopProxy

创建 AOP 代理,如果激活了,就需要有激活通知

1
2
3
4
5
6
7
8
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
// 监听调用 AdvisedSupportListener 实现类的 activated 方法
activate();
}
// 通过 AopProxyFactory 获得 AopProxy ,这个 AopProxyFactory 是在初始化函数中定义的,使用的是 DefaultAopProxyFactory
return getAopProxyFactory().createAopProxy(this);
}

定位: org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 这段代码用来判断选择哪种创建代理对象的方式
// config.isOptimize() 是否对代理类的生成使用策略优化 其作用是和 isProxyTargetClass 是一样的 默认为 false
// config.isProxyTargetClass() 是否使用 Cglib 的方式创建代理对象 默认为 false
// hasNoUserSuppliedProxyInterfaces 目标类是否有接口存在 且只有一个接口的时候接口类型不是SpringProxy 类型
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
// 上面的三个方法有一个为true的话,则进入到这里
// 从AdvisedSupport中获取目标类 类对象
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.");
}
// 判断目标类是否是接口 如果目标类是接口的话,则还是使用JDK的方式生成代理对象
// 如果目标类是 Proxy 类型 则还是使用 JDK 的方式生成代理对象
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 配置了使用 Cglib 进行动态代理或者目标类没有接口,那么使用 Cglib 的方式创建代理对象
return new ObjenesisCglibAopProxy(config);
}
else {
// 使用 JDK 的提供的代理方式生成代理对象
return new JdkDynamicAopProxy(config);
}
}

JdkDynamicAopProxy

JdkDynamicAopProxy#getProxy

定位: org.springframework.aop.framework.JdkDynamicAopProxy#getProxy

创建代理对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// 获取 AdvisedSupport 类型对象的所有接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
// 接口是否定义了 equals 和 hashcode 方法 (正常是没有的)
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 创建代理对象 this 是 JdkDynamicAopProxy
// JdkDynamicAopProxy 同时实现了 InvocationHandler 接口
// 这里我们生成的代理对象可以向上造型为任意 proxiedInterfaces 中的类型
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

定位: org.springframework.aop.framework.AopProxyUtils#completeProxiedInterfaces

获取目标类上的接口并且判断是否需要添加 SpringProxy Advised DecoratingProxy 接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
// 获取AdvisedSupport类型中目标类的接口
Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
// 如果目标类没有实现接口的话
if (specifiedInterfaces.length == 0) {
// No user-specified interfaces: check whether target class is an interface.
// 获取目标类
Class<?> targetClass = advised.getTargetClass();
if (targetClass != null) {
// 如果目标类是接口,则把目标类添加到AdvisedSupport的接口集合中
if (targetClass.isInterface()) {
advised.setInterfaces(targetClass);
}
// 如果是Proxy类型
else if (Proxy.isProxyClass(targetClass)) {
advised.setInterfaces(targetClass.getInterfaces());
}
// 重新获取接口
specifiedInterfaces = advised.getProxiedInterfaces();
}
}
//接口中有没有 SpringProxy 类型的接口
//是否需要添加 SpringProxy 接口
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
// isOpaque 代表生成的代理是否避免转化为 Advised 类型 默认为 false 如果目标类没有实现 Advised 接口
// 是否需要添加 Advised 接口
boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
// 是否需要添加 DecoratingProxy 接口
boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
int nonUserIfcCount = 0;
// 需要添加 SpringProxy 接口
if (addSpringProxy) {
nonUserIfcCount++;
}
// 需要添加通知
if (addAdvised) {
nonUserIfcCount++;
}
// 需要添加 DecoratingProxy 接口
if (addDecoratingProxy) {
nonUserIfcCount++;
}
Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
// 扩展接口数组
System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
int index = specifiedInterfaces.length;
if (addSpringProxy) {
// 为目标对象接口中添加 SpringProxy 接口
proxiedInterfaces[index] = SpringProxy.class;
index++;
}
if (addAdvised) {
// 为目标对象接口中添加 Advised 接口
proxiedInterfaces[index] = Advised.class;
index++;
}
if (addDecoratingProxy) {
// 为目标对象接口中添加 DecoratingProxy 接口
proxiedInterfaces[index] = DecoratingProxy.class;
}
return proxiedInterfaces;
}

JdkDynamicAopProxy#invoke (执行入口)

定位: org.springframework.aop.framework.JdkDynamicAopProxy#invoke

被拦截的接口方法的入口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;

// 获取到我们的目标对象
TargetSource targetSource = this.advised.targetSource;
Object target = null;

try {
// 若是 equals 方法不需要代理
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
// 若是 hashCode 方法不需要代理
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
// 若是 DecoratingProxy 也不要拦截器执行
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
// isAssignableFrom 方法:如果调用这个方法的 class 或接口与参数 cls 表示的类或接口相同,或者是参数 cls 表示的类或接口的父类,则返回 true
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}

Object retVal;

/**
* 这个配置是暴露我们的代理对象到线程变量中,需要搭配@EnableAspectJAutoProxy(exposeProxy = true)一起使用
* 比如在目标对象方法中再次获取代理对象可以使用这个AopContext.currentProxy()
* 还有的就是事务方法调用事务方法的时候也是用到这个
*/
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
// 把我们的代理对象暴露到线程变量中
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}

// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
// 获取我们的目标对象
target = targetSource.getTarget();
// 获取我们目标对象的 class
Class<?> targetClass = (target != null ? target.getClass() : null);

// Get the interception chain for this method.
// 从 Advised 中根据方法名和目标类获取AOP拦截器执行链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
// 如果拦截器链为空
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
// 通过反射直接调用执行
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 如果没有发现任何拦截器那么直接调用切点方法
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
// 将拦截器封装在 ReflectiveMethodInvocation,以便于使用其 proceed 进行处理
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
// 执行拦截器链
retVal = invocation.proceed();
}

// Massage return value if necessary.
// 获取返回类型
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
// 返回值类型错误
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
// 如果目标对象不为空且目标对象是可变的,如prototype类型
// 通常我们的目标对象都是单例的,即targetSource.isStatic为true
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
// 释放目标对象
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
// 线程上下文复位
AopContext.setCurrentProxy(oldProxy);
}
}
}

ObjenesisCglibAopProxy

CglibAopProxy#getProxy

定位:org.springframework.aop.framework.CglibAopProxy#getProxy

创建代理对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}

try {
// 从advised中获取ioc容器中配置的target对象
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

Class<?> proxySuperClass = rootClass;
//如果目标对象已经是CGLIB 生成代理对象(就是比较类名称中有 $$ 字符串),那么就取目标对象的父类作为目标对象的类
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
// 获取原始父类的接口
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}

// Validate the class, writing log messages as necessary.
// 打印出不能代理的方法名,CGLIB 是使用继承实现的,所以final , static 的方法不能被增强
validateClassIfNecessary(proxySuperClass, classLoader);

// Configure CGLIB Enhancer...
// 创建及配置Enhancer
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
// 配置超类,代理类实现的接口,回调方法等
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

// 获取callbacks
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);

// Generate the proxy class and create a proxy instance.
// 通过 Enhancer 生成代理对象,并设置回调
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}

定位: org.springframework.aop.framework.CglibAopProxy#createProxyClassAndInstance

1
2
3
4
5
6
7
8
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
enhancer.setInterceptDuringConstruction(false);
enhancer.setCallbacks(callbacks);
// 生成代理类以及创建代理
return (this.constructorArgs != null && this.constructorArgTypes != null ?
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
enhancer.create());
}

CglibAopProxy#getCallbacks

定位: org.springframework.aop.framework.CglibAopProxy#getCallbacks

被代理方法的回调

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
// 对于 expose-proxy 属性的处理,是否暴露当前对象为 ThreadLocal 模式,在当前上下文中能够进行引用
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();

// Choose an "aop" interceptor (used for AOP calls).
// 将拦截器封装在 DynamicAdvisedInterceptor 中
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = (isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
}
else {
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}

// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());

Callback[] mainCallbacks = new Callback[] {
// 将拦截器链加入 Callback 中
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};

Callback[] callbacks;

// If the target is a static one and the advice chain is frozen,
// then we can make some optimizations by sending the AOP calls
// direct to the target using the fixed chain for that method.
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);

// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
Method method = methods[x];
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(method, x);
}

// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}

DynamicAdvisedInterceptor#intercept (执行入口)

定位: org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 从advised中获取配置好的AOP通知
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
// 如果没有 aop 通知配置,那么直接调用 target 对象的调用方法
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 如果拦截器链为空则直接激活原方法
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
// 通过cglibMethodInvocation来启动advice通知
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}

getInterceptorsAndDynamicInterceptionAdvice

定位: org.springframework.aop.framework.AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice

1
2
3
4
5
6
7
8
9
10
11
12
13
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
// 创建一个 method 的缓存对象,在 MethodCacheKey 中实现了 equals 和 hashCode 方法同时还实现了compareTo 方法
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
// 先从缓存中获取,如果缓存中获取不到,则再调用方法获取,获取之后放入到缓存中
if (cached == null) {
// 调用的是 advisorChainFactory 的 getInterceptorsAndDynamicInterceptionAdvice方法
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}

定位: org.springframework.aop.framework.DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {

// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
// 这里用了一个单例模式 获取 DefaultAdvisorAdapterRegistry 实例
// 在 Spring 中把每一个功能都分的很细,每个功能都会有相应的类去处理 符合单一职责原则的地方很多 这也是值得我们借鉴的一个地方
// AdvisorAdapterRegistry 这个类的主要作用是将 Advice 适配为 Advisor 将 Advisor 适配为对应的 MethodInterceptor
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
// 创建一个初始大小为 之前获取到的 通知个数的集合
List<Object> interceptorList = new ArrayList<>(advisors.length);
// 如果目标类为null的话,则从方法签名中获取目标类
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
// 判断目标类是否存在引介增强,通常为 false
Boolean hasIntroductions = null;

// 循环目标方法匹配的通知
for (Advisor advisor : advisors) {
// 如果是 PointcutAdvisor 类型的实例
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 如果提前进行过切点的匹配了或者当前的 Advisor 适用于目标类
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
//检测Advisor是否适用于此目标方法
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
if (match) {
// 拦截器链是通过 AdvisorAdapterRegistry 来加入的,这个AdvisorAdapterRegistry 对 advice 织入具备很大的作用
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
// 使用 MethodMatchers 的 matches 方法进行匹配判断
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
// 动态切入点则会创建一个 InterceptorAndDynamicMethodMatcher 对象
// 这个对象包含 MethodInterceptor 和 MethodMatcher 的实例
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
// 添加到列表中
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
// 如果是引介增强
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
// 将 Advisor 转换为 Interceptor
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
// 以上两种都不是
else {
// 将 Advisor 转换为 Interceptor
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}

return interceptorList;
}

AspectJAwareAdvisorAutoProxyCreator

img

定位: org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator

AbstractAutoProxyCreator

getEarlyBeanReference

定位: org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getEarlyBeanReference

三级缓存使用到

1
2
3
4
5
6
7
8
9
/**  
* 放到集合中,然后判断要不要包装,其实就是在循环依赖注入属性的时候如果有AOP代理的话,也会进行代理,然后返回
*/
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.put(cacheKey, bean);
return wrapIfNecessary(bean, beanName, cacheKey);
}

postProcessBeforeInstantiation

定位: org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation

bean 实例化之前, 对 自定义的 TargetSource 进行代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);

if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
//查缓存,是否有处理过了,不管是不是需要通知增强的,只要处理过了就会放里面
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
// 要跳过的直接设置FALSE
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,请在此处创建代理;抑制不必要的目标bean的默认实例化, TargetSource将以自定义方式处理目标实例。
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;
}

postProcessAfterInitialization

定位: org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization

初始化完成后创建代理对象

1
2
3
4
5
6
7
8
9
10
11
12
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 获取当前 bean 的缓存 key:如果 beanName 不为空,则以 beanName 为 key,如果为FactoryBean 类型,前面会添加 & 符号;如果 beanName 为空,则以当前 bean 对应的 class 为 key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 判断当前 bean 是否正在被代理,如果正在被代理则不进行封装
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 如果它需要被代理,则需要封装指定的 bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}

wrapIfNecessary

定位: org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary

先判断是否已经处理过,是否需要跳过,跳过的话直接就放进advisedBeans里,表示不进行代理,如果这个bean处理过了,获取通知拦截器,然后开始进行代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
*
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 如果已经处理过,直接返回
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 这里 advisedBeans 缓存了已经进行了代理的 bean ,如果缓存中存在,则可以直接返回
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 这里 isInfrastructureClass() 用于判断当前 bean 是否为 Spring 容器内部的 bean,内部的bean 是不用进行代理的;shouldSkip() 则用于判断当前 bean 是否应该被跳过
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
// 对当前bean进行缓存
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

// Create proxy if we have advice.
// 获取当前 bean 的 Advices 和 Advisors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 对当前bean的代理状态进行缓存
if (specificInterceptors != DO_NOT_PROXY) {
// 对当前 bean 的代理状态进行缓存
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 根据获取到的Advices和Advisors为当前bean生成代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
// 缓存生成的代理bean的类型,并且返回生成的代理bean
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}

this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

createProxy

定位: org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy

进行代理工厂的创建,然后判断是否需要设置 proxyTargetClass,以便于后面决定是不是要进行 jdk动态代理还是 cglib 的动态代理, 然后把通知器 advisors 包装下,加入到代理工厂,获取代理对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {

// 给bean定义设置暴露属性
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}

// 创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
// 获取当前类中相关属性
proxyFactory.copyFrom(this);
// 决定对于给定的bean是否应该使用targetClass而不是他的接口代理,检查proxyTargetClass设置以及preserverTargetClass属性
if (!proxyFactory.isProxyTargetClass()) {
// 判断是 使用jdk动态代理 还是cglib代理
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// 添加代理接口
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}

// 构建增强器
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
// 设置到要代理的类
proxyFactory.setTargetSource(targetSource);
// 定制代理
customizeProxyFactory(proxyFactory);

// 控制代理工厂被配置之后,是否还允许修改通知,默认值是 false
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 真正创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}


protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
// 解析注册的所有interceptorName
Advisor[] commonInterceptors = resolveInterceptorNames();

List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
// 加入拦截器
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors.length > 0) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
if (logger.isTraceEnabled()) {
int nrOfCommonInterceptors = commonInterceptors.length;
int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
}

Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
// 拦截器进行封装转化为Advisor
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}

advisorAdapterRegistry#wrap

org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry#wrap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
// 如果要封装的对象本身就是Advisor类型,那么无须做任何处理
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
// 如果类型不是 Advisor 和 Advice 两种类型的数据,那么将不能进行封装
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
// 如果是 MethodInterceptor 类型则使用 DefaultPointcutAdvisor 封装
return new DefaultPointcutAdvisor(advice);
}
// 如果存在 Advisor 的适配器那么也同样需要进行封装
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
// 默认支持这 3 种 MethodBeforeAdviceAdapter / AfterReturningAdviceAdapter / ThrowsAdviceAdapter
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}

ProxyProcessorSupport

定位: org.springframework.aop.framework.ProxyProcessorSupport

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
* 判断接口是不是需要设置 ProxyTargetClass = true,判断它的接口不是内部的回调接口和内部语言接口,就添加接口否则就设置 ProxyTargetClass = true
*/
protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
boolean hasReasonableProxyInterface = false;
for (Class<?> ifc : targetInterfaces) {
if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
ifc.getMethods().length > 0) {
// 用接口代理,也就是jdk
hasReasonableProxyInterface = true;
break;
}
}
// 有接口
if (hasReasonableProxyInterface) {
// Must allow for introductions; can't just set interfaces to the target's interfaces only.
for (Class<?> ifc : targetInterfaces) {
proxyFactory.addInterface(ifc);
}
}
else {
// 没接口就设置 true
proxyFactory.setProxyTargetClass(true);
}
}
/**
* 判断是不是 Spring 容器内部的接口
*
*/
protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
return (InitializingBean.class == ifc || DisposableBean.class == ifc || Closeable.class == ifc ||
AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
}
/**
* 判断是不是一些已知的内部语言接口
*/
protected boolean isInternalLanguageInterface(Class<?> ifc) {
return (ifc.getName().equals("groovy.lang.GroovyObject") ||
ifc.getName().endsWith(".cglib.proxy.Factory") ||
ifc.getName().endsWith(".bytebuddy.MockAccess"));
}

AbstractAdvisorAutoProxyCreator

getAdvicesAndAdvisorsForBean

定位: org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean

1
2
3
4
5
6
7
8
9
10
11
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

// 找合适的增强器对象
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
// 若为空表示没找到
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}

findEligibleAdvisors

定位: org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors

1
2
3
4
5
6
7
8
9
10
11
12
13
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 将当前容器中所有的切面类的切面逻辑进行封装,从而得到目标 Advisor 实例
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 对获取到的所有 Advisor 进行判断,看其切面定义是否可以应用到当前 bean,从而得到最终需要应用的 Advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 提供的 hook 方法,用于对目标 Advisor 进行扩展
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 对需要代理的 Advisor 按照一定的规则进行排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}

extendAdvisors

定位: org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#extendAdvisors

将 ExposeInvocationInterceptor 添加到 advice 链的开头。使用AspectJ切入点表达式时需要此附加建议,以及在使用AspectJ风格的建议时。

1
2
3
protected void extendAdvisors(List<Advisor> candidateAdvisors) {
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
}

定位: org.springframework.aop.aspectj.AspectJProxyUtils#makeAdvisorChainAspectJCapableIfNecessary

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
// Don't add advisors to an empty list; may indicate that proxying is just not required
if (!advisors.isEmpty()) {
boolean foundAspectJAdvice = false;
for (Advisor advisor : advisors) {
// Be careful not to get the Advice without a guard, as this might eagerly
// instantiate a non-singleton AspectJ aspect...
if (isAspectJAdvice(advisor)) {
foundAspectJAdvice = true;
break;
}
}
// 存在 AspectJAdvice, 但是不存在 ExposeInvocationInterceptor
if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
// 添加 advice 链开头
advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
return true;
}
}
return false;
}

AopUtils#findAdvisorsThatCanApply

定位: org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
// 若候选的增强器集合为空 直接返回
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
// 定义一个合适的增强器集合对象
List<Advisor> eligibleAdvisors = new ArrayList<>();
// 循环我们候选的增强器对象
for (Advisor candidate : candidateAdvisors) {
// 判断我们的增强器对象是不是实现了IntroductionAdvisor (很明显我们事务的没有实现 所以不会走下面的逻辑)
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
// 是否有引介增强
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
// 判断我们的增强器对象是不是实现了IntroductionAdvisor
if (candidate instanceof IntroductionAdvisor) {
// already processed
// 在上面已经处理过,不需要处理
continue;
}

// 真正的判断增强器是否合适当前类型
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}

// 对 pointcut 表达式进行匹配
// 进行切点表达式的匹配最重要的就是 ClassFilter 和 MethodMatcher 这两个方法的实现。
// MethodMatcher 中有两个 matches 方法。一个参数是只有 Method 对象和 targetClass,另一个参数有
// Method 对象和 targetClass 对象还有一个 Method 的方法参数,他们两个的区别是:
// 两个参数的 matches 是用于静态的方法匹配 三个参数的 matches 是在运行期动态的进行方法匹配的
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
// 先进行 ClassFilter 的 matches 方法校验
// 首先这个类要在所匹配的规则下
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}

// 再进行 MethodMatcher 方法级别的校验
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}

// 判断匹配器是不是 IntroductionAwareMethodMatcher
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}

// 创建一个集合用于保存 targetClass 的 class 对象
Set<Class<?>> classes = new LinkedHashSet<>();
// 判断当前 class 是不是代理的 class 对象
if (!Proxy.isProxyClass(targetClass)) {
// 加入到集合中去
classes.add(ClassUtils.getUserClass(targetClass));
}
// 获取到 targetClass 所实现的接口的 class 对象,然后加入到集合中
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

// 循环所有的 class 对象
for (Class<?> clazz : classes) {
// 通过 class 获取到所有的方法
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
// 循环我们的方法
for (Method method : methods) {
// 只要有一个方法能匹配到就返回 true
// 这里就会有一个问题:因为在一个目标中可能会有多个方法存在,有的方法是满足这个切点的匹配规则的
// 但是也可能有一些方法是不匹配切点规则的,这里检测的是只有一个 Method 满足切点规则就返回 true
// 所以在运行时进行方法拦截的时候还会有一次运行时的方法切点规则匹配
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
// 通过方法匹配器进行匹配
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}

开始

简单的 xml 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

<bean id="logUtil" class="com.devinx3.demo.aop.xml.util.LogUtil"/>
<bean class="com.devinx3.demo.aop.xml.service.DemoService"/>

<!-- 如果已经配置了 aop:config, 则无需此标签 -->
<!-- <aop:aspectj-autoproxy /> -->

<aop:config>
<aop:aspect ref="logUtil">
<aop:pointcut id="logPoint"
expression="execution( Object com.devinx3.demo.aop.xml.service.DemoService.* (..))"/>
<aop:around method="around" pointcut-ref="logPoint"/>
<aop:before method="start" pointcut-ref="logPoint"/>
<aop:after method="logFinally" pointcut-ref="logPoint"/>
<aop:after-returning method="stop" pointcut-ref="logPoint" returning="result"/>
<aop:after-throwing method="logException" pointcut-ref="logPoint" throwing="e"/>
</aop:aspect>
</aop:config>
</beans>

解析 AOP 配置文件

AopNamespaceHandler

定位: org.springframework.aop.config.AopNamespaceHandler

注册 aop 标签的解析器

1
2
3
4
5
6
7
8
public void init() {  
// In 2.0 XSD as well as in 2.5+ XSDs
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// Only in 2.0 XSD: moved to context namespace in 2.5+
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}

config 标签解析器

定位: org.springframework.aop.config.ConfigBeanDefinitionParser

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public BeanDefinition parse(Element element, ParserContext parserContext) {
CompositeComponentDefinition compositeDef =
new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compositeDef);
// 注册自动代理模式创建器, AspectjAwareAdvisorAutoProxyCreator (aspectj-autoproxy)
configureAutoProxyCreator(parserContext, element);
// 解析 aop:config 子节点下的 aop:pointcut/aop:advice/aop:aspect
List<Element> childElts = DomUtils.getChildElements(element);
for (Element elt: childElts) {
String localName = parserContext.getDelegate().getLocalName(elt);
if (POINTCUT.equals(localName)) {
parsePointcut(elt, parserContext);
} else if (ADVISOR.equals(localName)) {
parseAdvisor(elt, parserContext);
} else if (ASPECT.equals(localName)) {
parseAspect(elt, parserContext);
}
}
parserContext.popAndRegisterContainingComponent();
return null;
}
解析 pointcut 标签

解析 pointcut 并构造 AspectJExpressionPointcut 元信息, 注册到 ben 工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
private AbstractBeanDefinition parsePointcut(Element pointcutElement, ParserContext parserContext) {
// 切入点的唯一标识
String id = pointcutElement.getAttribute(ID);
// 获取切入点的表达式
String expression = pointcutElement.getAttribute(EXPRESSION);
AbstractBeanDefinition pointcutDefinition = null;
try {
// 采用栈保存切入点
this.parseState.push(new PointcutEntry(id));
// 创建切入点bean对象
// beanClass为AspectJExpressionPointcut.class。并且设置属性expression到该beanClass
pointcutDefinition = createPointcutDefinition(expression);
pointcutDefinition.setSource(parserContext.extractSource(pointcutElement));
String pointcutBeanName = id;
// 注册 BeanDefinition
if (StringUtils.hasText(pointcutBeanName)) {
parserContext.getRegistry().registerBeanDefinition(pointcutBeanName, pointcutDefinition);
} else {
// 生成 BeanDefinition 的名称
pointcutBeanName = parserContext.getReaderContext().registerWithGeneratedName(pointcutDefinition);
}
parserContext.registerComponent(
new PointcutComponentDefinition(pointcutBeanName, pointcutDefinition, expression));
}
finally {
// 创建后移除
this.parseState.pop();
}
return pointcutDefinition;
}
// 创建 pointcut 的 bean 元信息
protected AbstractBeanDefinition createPointcutDefinition(String expression) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(AspectJExpressionPointcut.class);
beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
beanDefinition.setSynthetic(true);
beanDefinition.getPropertyValues().add(EXPRESSION, expression);
return beanDefinition;
}
解析 advice 标签

包含 around, before, after, after-returning, after-throwing

解析 pointcut 并构造 AspectJExpressionPointcut 元信息,
解析 around, before, after, after-returning, after-throwing 并构造 AspectJMethodBeforeAdvice, AspectJAfterAdvice, AspectJAfterReturningAdvice, AspectJAfterThrowingAdvice, AspectJAroundAdvice 元信息
同时构造 AspectJPointcutAdvisor 元信息,并注册到 bean 工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// 解析通知类并注册到 bean 工厂(org.springframework.aop.aspectj.AspectJPointcutAdvisor)
private AbstractBeanDefinition parseAdvice(
String aspectName, int order, Element aspectElement, Element adviceElement, ParserContext parserContext,
List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) {

try {
this.parseState.push(new AdviceEntry(parserContext.getDelegate().getLocalName(adviceElement)));

// create the method factory bean
// 解析 advice 节点中的 "method" 属性,并包装为 MethodLocatingFactoryBean 对象
RootBeanDefinition methodDefinition = new RootBeanDefinition(MethodLocatingFactoryBean.class);
methodDefinition.getPropertyValues().add("targetBeanName", aspectName);
methodDefinition.getPropertyValues().add("methodName", adviceElement.getAttribute("method"));
methodDefinition.setSynthetic(true);

// create instance factory definition
// 关联 aspectName,包装为 SimpleBeanFactoryAwareAspectInstanceFactory 对象
RootBeanDefinition aspectFactoryDef =
new RootBeanDefinition(SimpleBeanFactoryAwareAspectInstanceFactory.class);
aspectFactoryDef.getPropertyValues().add("aspectBeanName", aspectName);
aspectFactoryDef.setSynthetic(true);

// register the pointcut
// 涉及 point-cut 属性的解析,并结合上述的两个 bean 最终包装为 AbstractAspectJAdvice通知对象
AbstractBeanDefinition adviceDef = createAdviceDefinition(
adviceElement, parserContext, aspectName, order, methodDefinition, aspectFactoryDef,
beanDefinitions, beanReferences);

// configure the advisor
// 最终包装为 AspectJPointcutAdvisor 对象
RootBeanDefinition advisorDefinition = new RootBeanDefinition(AspectJPointcutAdvisor.class);
advisorDefinition.setSource(parserContext.extractSource(adviceElement));
advisorDefinition.getConstructorArgumentValues().addGenericArgumentValue(adviceDef);
if (aspectElement.hasAttribute(ORDER_PROPERTY)) {
advisorDefinition.getPropertyValues().add(
ORDER_PROPERTY, aspectElement.getAttribute(ORDER_PROPERTY));
}
// register the final advisor
parserContext.getReaderContext().registerWithGeneratedName(advisorDefinition);

return advisorDefinition;
}
finally {
this.parseState.pop();
}
}

创建通知 的 bean 元信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
private AbstractBeanDefinition createAdviceDefinition(
Element adviceElement, ParserContext parserContext, String aspectName, int order,
RootBeanDefinition methodDef, RootBeanDefinition aspectFactoryDef,
List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) {

// 首先根据adviceElement节点分析出是什么类型的Advice
RootBeanDefinition adviceDefinition = new RootBeanDefinition(getAdviceClass(adviceElement, parserContext));
adviceDefinition.setSource(parserContext.extractSource(adviceElement));

// 设置aspectName属性和declarationOrder属性
adviceDefinition.getPropertyValues().add(ASPECT_NAME_PROPERTY, aspectName);
adviceDefinition.getPropertyValues().add(DECLARATION_ORDER_PROPERTY, order);

// 解析节点是否含有`returning`/`throwing`/`arg-names`,有则设置
if (adviceElement.hasAttribute(RETURNING)) {
adviceDefinition.getPropertyValues().add(
RETURNING_PROPERTY, adviceElement.getAttribute(RETURNING));
}
if (adviceElement.hasAttribute(THROWING)) {
adviceDefinition.getPropertyValues().add(
THROWING_PROPERTY, adviceElement.getAttribute(THROWING));
}
if (adviceElement.hasAttribute(ARG_NAMES)) {
adviceDefinition.getPropertyValues().add(
ARG_NAMES_PROPERTY, adviceElement.getAttribute(ARG_NAMES));
}

// 设置构造函数的入参变量
// Method/AspectJExpressionPointcut/AspectInstanceFactory三个入参
ConstructorArgumentValues cav = adviceDefinition.getConstructorArgumentValues();
cav.addIndexedArgumentValue(METHOD_INDEX, methodDef);

// 解析 pointcut 属性
Object pointcut = parsePointcutProperty(adviceElement, parserContext);
if (pointcut instanceof BeanDefinition) {
cav.addIndexedArgumentValue(POINTCUT_INDEX, pointcut);
beanDefinitions.add((BeanDefinition) pointcut);
}
else if (pointcut instanceof String) {
RuntimeBeanReference pointcutRef = new RuntimeBeanReference((String) pointcut);
cav.addIndexedArgumentValue(POINTCUT_INDEX, pointcutRef);
beanReferences.add(pointcutRef);
}
cav.addIndexedArgumentValue(ASPECT_INSTANCE_FACTORY_INDEX, aspectFactoryDef);

return adviceDefinition;
}
// 根据不同的标签使用对应的 advice
private Class<?> getAdviceClass(Element adviceElement, ParserContext parserContext) {
String elementName = parserContext.getDelegate().getLocalName(adviceElement);
if (BEFORE.equals(elementName)) {
return AspectJMethodBeforeAdvice.class;
}
else if (AFTER.equals(elementName)) {
return AspectJAfterAdvice.class;
}
else if (AFTER_RETURNING_ELEMENT.equals(elementName)) {
return AspectJAfterReturningAdvice.class;
}
else if (AFTER_THROWING_ELEMENT.equals(elementName)) {
return AspectJAfterThrowingAdvice.class;
}
else if (AROUND.equals(elementName)) {
return AspectJAroundAdvice.class;
}
else {
throw new IllegalArgumentException("Unknown advice kind [" + elementName + "].");
}
}
解析 advisor 标签

解析 advisor 并构造 DefaultBeanFactoryPointcutAdvisor 元信息, 注册到 ben 工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
private void parseAdvisor(Element advisorElement, ParserContext parserContext) {
// 解析 <aop:advisor> 节点,最终创建的 beanClass 为 DefaultBeanFactoryPointcutAdvisor
// 另外 advice-ref 属性必须定义,其与内部属性 adviceBeanName 对应
AbstractBeanDefinition advisorDef = createAdvisorBeanDefinition(advisorElement, parserContext);
String id = advisorElement.getAttribute(ID);
try {
this.parseState.push(new AdvisorEntry(id));
String advisorBeanName = id;
// 注册到 bean 工厂
if (StringUtils.hasText(advisorBeanName)) {
parserContext.getRegistry().registerBeanDefinition(advisorBeanName, advisorDef);
}
else {
advisorBeanName = parserContext.getReaderContext().registerWithGeneratedName(advisorDef);
}
// 解析 pointcut 属性并赋值到 DefaultBeanFactoryPointcutAdvisor#pointcut 内部属性
Object pointcut = parsePointcutProperty(advisorElement, parserContext);
if (pointcut instanceof BeanDefinition) {
advisorDef.getPropertyValues().add(POINTCUT, pointcut);
parserContext.registerComponent(
new AdvisorComponentDefinition(advisorBeanName, advisorDef, (BeanDefinition) pointcut));
}
else if (pointcut instanceof String) {
advisorDef.getPropertyValues().add(POINTCUT, new RuntimeBeanReference((String) pointcut));
parserContext.registerComponent(
new AdvisorComponentDefinition(advisorBeanName, advisorDef));
}
}
finally {
this.parseState.pop();
}
}

简介

阅读 Spring AOP 源码,是深入理解 Spring 框架核心机制的一次重要学习经历。通过研究 AOP(面向切面编程)的实现,能够窥探 Spring 如何处理横切关注点。

AOP 概念

img

引用博客: https://blog.csdn.net/qq_31960623/article/details/119964881

在那些类的那个方法(pointcut), 的那个地方(advice before/after/around), 处理什么逻辑(advice method)

源码流程图

https://www.processon.com/view/link/658454b4e2e8734477e1f1d6

目录

SpringAOP 源码之配置

SpringAOP 源码之 bean 创建

SpringAOP 源码之创建代理对象及执行

SpringAOP 源码之常用的 Advice

SpringAOP 源码之事务

0%