在源码笔记(一)中,咱们留下了几个问题:java
今天这篇文章将要谈一谈第一个问题:Spring Boot是怎么扫描到咱们的bean里面有 Transactional 这个注解,而且把 InfrastructureAdvisorAutoProxyCreator 这个 BeanPostProcessor注册到bean的信息里面去的spring
在笔记一里面咱们提到,在生成cglib proxy的过程当中,会在 AbstractAutowireCapableBeanFactory里面调用 getBeanPostProcessors方法,这个方法返回的是一个叫beanPostProcessors的成员变量,经过搜索咱们发现,AbstractAutowireCapableBeanFactory 的父类 AbstractBeanFactory有一个addBeanPostProcessor的方法,这个方法会把咱们须要跟踪的InfrastructureAdvisorAutoProxyCreator加到beanPostProcessors这个list中。经过断点,咱们能够看到如今已经找到了InfrastructureAdvisorAutoProxyCreator被加到list中,左边红色的方框是调用栈,能够看到代码调用的顺序。 post
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
复制代码
经过debug看到这个postProcessorNames变量的值以下图,红色框出来的是InfrastructureAdvisorAutoProxyCreator这个bean的名称。 阅读代码咱们知道postProcessorNames来源于getBeanNamesForType,咱们有必要跟踪进去,看看这个getBeanNamesForType作了什么。this
回到InfrastructureAdvisorAutoProxyCreator,咱们看看是否是它在处理bean的时候解析了Transactional注解。它的父类AbstractAutoProxyCreator的方法wrapIfNecessary中有如下一段代码:spa
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
复制代码
跳转到AbstractAdvisorAutoProxyCreator的方法getAdvicesAndAdvisorsForBean,其中有这样一段代码:debug
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
复制代码
跳转到findEligibleAdvisors,其中有一段代码:code
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
复制代码
进到findAdvisorsThatCanApply方法,看到如下代码:cdn
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
复制代码
跟着程序执行的顺序,最后走到了AopUtils的方法canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions),方法中有一段代码blog
if ((introductionAwareMethodMatcher != null &&
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
methodMatcher.matches(method, targetClass)) {
return true;
}
复制代码
进到methodMatcher.matches,看到下面这段代码:ci
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
复制代码
接着进入tas.getTransactionAttribute最终会来到类AbstractFallbackTransactionAttributeSource,在它的getTransactionAttribute方法中,咱们重点看一下下面这行代码:
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
复制代码
进到方法的里面,执行到下面代码:
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
复制代码
findTransactionAttribute 方法由AbstractFallbackTransactionAttributeSource的子类AnnotationTransactionAttributeSource 实现,继续跟踪到了determineTransactionAttribute方法,能够看到这个方法的代码是这样的:
if (ae.getAnnotations().length > 0) {
for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae);
if (attr != null) {
return attr;
}
}
}
return null;
复制代码
终于开始判断方法上面注解的个数,这可能意味着咱们快要找到spring是在哪儿解析Transactional注解了。咱们接着往下执行,进到了SpringTransactionAnnotationParser类中,它的方法parseTransactionAnnotation有这么一段代码:
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ae, Transactional.class);
复制代码
这一段就是用来解析咱们transactional注解的,至此咱们已经找到了spring是在什么地方解析bean里面的transactional注解的。
本期解决了笔记(一)留下的两个问题中一个,接下来会花一些时间来跟踪一下cglib proxy对带有Transactional注解的方法作了什么。
插播一段广告,阿里巴巴长期招聘,有须要内推的朋友能够加脉脉私聊,或者简历发到linlan.zcj@alibaba-inc.com