既然事务是用AoP实现的,自然也会经历一个完整的AoP过程。
切面方法查找
AnnotationAwareAspectJAutoProxyCreator->findCandidateAdvisors():
// Spring中的切面方法,如事务的切面方法
List<Advisor> advisors = super.findCandidateAdvisors();
AbstractAdvisorAutoProxyCreator->findCandidateAdvisors():
return this.advisorRetrievalHelper.findAdvisorBeans();
BeanFactoryAdvisorRetrievalHelper->findAdvisorBeans():
// 获取IoC容器中所有beanName,查找实现了Advisor接口的类,实例化之后返回
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
这里返回的beanName为org.springframework.transaction.config.internalTransactionAdvisor,对应的实体类BeanFactoryTransactionAttributeSourceAdvisor也确实实现了Advisor接口,是在ProxyTransactionManagementConfiguration类中导入的,如图。
切面表达式
事务切面类跳过了切面表达式的验证,只判断方法是否符合切面表达式
TransactionAttributeSourcePointcut->matches():
if (TransactionalProxy.class.isAssignableFrom(targetClass) ||
PlatformTransactionManager.class.isAssignableFrom(targetClass) ||
PersistenceExceptionTranslator.class.isAssignableFrom(targetClass)) {
return false;
}
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
AbstractFallbackTransactionAttributeSource->getTransactionAttribute():
if (method.getDeclaringClass() == Object.class) {
return null;
}
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
// 放入缓存,这样下次判断的时候就知道这个方法是否符合切面表达式了
......
AbstractFallbackTransactionAttributeSource->computeTransactionAttribute():
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// 先看方法是否含有@Transactional注解
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
// 如果方法没有,看类是否含有@Transactional注解
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
AnnotationTransactionAttributeSource->findTransactionAttribute():
return determineTransactionAttribute(method);
AnnotationTransactionAttributeSource->determineTransactionAttribute():
for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
if (attr != null) {
return attr;
}
}
SpringTransactionAnnotationParser->parseTransactionAnnotation():
// 查找所给方法或类是否含有@Transactional注解,有的话,解析注解的值,封装成TransactionAttribute对象返回,否则返回空
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
element, Transactional.class, false, false);
if (attributes != null) {
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
根据代码可知,以下几种不符合切面表达式:
- 目标类是
TransactionalProxy、PlatformTransactionManager、PersistenceExceptionTranslator类及其子类 - 目标类是
Object类 - 目标方法不以
public修饰 - 目标方法和目标类都没有@Transactional注解
看来,只要公共方法或类含有@Transactional注解,就满足切面表达式了