通过 https://www.yuque.com/zhanyifan-rkxpe/grf7g5/aqcdng 上一篇blog中都知道,事务通过在容器中添加了一个Advisor(BeanFactoryTransactionAttributeSourceAdvisor),以及对应的TransactionInceptor,来实现的事务。
在创建Bean时,调用通过@Import导入进来的BeanPostProcessor,在 postProcessBeforeInstantiation
中进行切面的解析,在postProcessAfterInitialization
进行创建动态代理。具体的解析切面流程如下。
调用postProcessBeforeInstantiation
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = this.getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// isInfrastructureClass 判断是否bean是否是一个切面类(Advisor/Advice这种)
// shouldSkip 中判断这个Bean是否需要跳过
if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// 这下面的基本都不会执行
TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
return null;
}
}
shouldSkip(AspectJAwareAdvisorAutoProxyCreator中重写了)
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 寻找候选的Advisor,这个方法在AnnotationAwareAspectJAutoProxyCreator中又重写了
List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
Iterator var4 = candidateAdvisors.iterator();
Advisor advisor;
do {
if (!var4.hasNext()) {
return super.shouldSkip(beanClass, beanName);
}
advisor = (Advisor)var4.next();
} while(!(advisor instanceof AspectJPointcutAdvisor) || !((AspectJPointcutAdvisor)advisor).getAspectName().equals(beanName));
return true;
}
AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors方法
protected List<Advisor> findCandidateAdvisors() {
// super方法是解析传统的通过Advisor类实现的切面
List<Advisor> advisors = super.findCandidateAdvisors();
if (this.aspectJAdvisorsBuilder != null) {
// 而这个方法,是通过@AspectJ方式来解析的切面
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
super.findCandidateAdvisors()
Spring Transaction 就是通过这个方法,在容器中自己添加了一个Advisor来实现的。
this.advisorRetrievalHelper.findAdvisorBeans();
// 关键代码,找到容器中所有的Advisor 类型的bean
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
aspectJAdvisorsBuilder.buildAspectJAdvisors()
// 部分代码
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized(this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList();
List<String> aspectNames = new ArrayList();
// 找出所有的Object(即所有的bean)
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
String[] var18 = beanNames;
int var19 = beanNames.length;
for(int var7 = 0; var7 < var19; ++var7) {
String beanName = var18[var7];
if (this.isEligibleBean(beanName)) {
Class<?> beanType = this.beanFactory.getType(beanName);
// 然后通过判断类上面是否标注了@AspectJ注解来判断是否要解析成一个切面,
// 然后将@Before这些东西,解析成Advisor,注册到容器中
if (beanType != null && this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
解析切面完成之后,就到了创建动态代理
wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
// 关键代码,用来找到符合这个Bean的切面
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
getAdvicesAndAdvisorsForBean
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray();
}
findEligibleAdvisors
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
// 找到可以应用的Advisor
List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
this.extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
findAdvisorsThatCanApply
protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
List var4;
try {
// 关键
var4 = AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
} finally {
ProxyCreationContext.setCurrentProxiedBeanName((String)null);
}
return var4;
}
调用Advisor中的pointCut,中的matches方法,进行切面的匹配
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor)advisor).getClassFilter().matches(targetClass);
} else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor)advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
} else {
return true;
}
}
所以,事务的切面匹配,也是这套流程,在 BeanFactoryTransactionAttributeSourceAdvisor,内部的pointCut类型为 TransactionAttributeSourcePointcut。
TransactionAttributeSourcePointcut#matches方法
public boolean matches(Method method, Class<?> targetClass) {
// 获取到的事务属性源,默认是 AnnotationTransactionAttributeSource
TransactionAttributeSource tas = this.getTransactionAttributeSource();
return tas == null || tas.getTransactionAttribute(method, targetClass) != null;
}
AnnotationTransactionAttributeSource的继承图谱
所以,调用的getTransactionAttribute方法为 org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource中的getTransactionAttribute。(这里,就是最关键的Transactional的解析)
@Nullable
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
// 判断是不是Object类型,是的话,直接走
if (method.getDeclaringClass() == Object.class) {
return null;
} else {
Object cacheKey = this.getCacheKey(method, targetClass);
TransactionAttribute cached = (TransactionAttribute)this.attributeCache.get(cacheKey);
if (cached != null) {
return cached == NULL_TRANSACTION_ATTRIBUTE ? null : cached;
} else {
// 查找@Transactional注解
TransactionAttribute txAttr = this.computeTransactionAttribute(method, targetClass);
// 找不到,放入一个默认的TransactionAttribute
if (txAttr == null) {
this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
} else {
String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
if (txAttr instanceof DefaultTransactionAttribute) {
((DefaultTransactionAttribute)txAttr).setDescriptor(methodIdentification);
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
}
this.attributeCache.put(cacheKey, txAttr);
}
return txAttr;
}
}
}
最关键的代码
@Nullable
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
// 判断这个方法是不是public的,如果不是,调用不了,走了
if (this.allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
} else {
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
// 第一步,找目标类,看有没有注解,有了直接返回
TransactionAttribute txAttr = this.findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
} else {
// 如果目标类没有,找实现类
txAttr = this.findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
} else {
if (specificMethod != method) {
// 找实现类的接口方法
txAttr = this.findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
// 找实现类的接口上
txAttr = this.findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
return null;
}
}
}
}