通过 https://www.yuque.com/zhanyifan-rkxpe/grf7g5/aqcdng 上一篇blog中都知道,事务通过在容器中添加了一个Advisor(BeanFactoryTransactionAttributeSourceAdvisor),以及对应的TransactionInceptor,来实现的事务。

在创建Bean时,调用通过@Import导入进来的BeanPostProcessor,在 postProcessBeforeInstantiation 中进行切面的解析,在postProcessAfterInitialization 进行创建动态代理。具体的解析切面流程如下。

调用postProcessBeforeInstantiation

  1. public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
  2. Object cacheKey = this.getCacheKey(beanClass, beanName);
  3. if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
  4. if (this.advisedBeans.containsKey(cacheKey)) {
  5. return null;
  6. }
  7. // isInfrastructureClass 判断是否bean是否是一个切面类(Advisor/Advice这种)
  8. // shouldSkip 中判断这个Bean是否需要跳过
  9. if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
  10. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  11. return null;
  12. }
  13. }
  14. // 这下面的基本都不会执行
  15. TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
  16. if (targetSource != null) {
  17. if (StringUtils.hasLength(beanName)) {
  18. this.targetSourcedBeans.add(beanName);
  19. }
  20. Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
  21. Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
  22. this.proxyTypes.put(cacheKey, proxy.getClass());
  23. return proxy;
  24. } else {
  25. return null;
  26. }
  27. }

shouldSkip(AspectJAwareAdvisorAutoProxyCreator中重写了)

  1. protected boolean shouldSkip(Class<?> beanClass, String beanName) {
  2. // 寻找候选的Advisor,这个方法在AnnotationAwareAspectJAutoProxyCreator中又重写了
  3. List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
  4. Iterator var4 = candidateAdvisors.iterator();
  5. Advisor advisor;
  6. do {
  7. if (!var4.hasNext()) {
  8. return super.shouldSkip(beanClass, beanName);
  9. }
  10. advisor = (Advisor)var4.next();
  11. } while(!(advisor instanceof AspectJPointcutAdvisor) || !((AspectJPointcutAdvisor)advisor).getAspectName().equals(beanName));
  12. return true;
  13. }

AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors方法

  1. protected List<Advisor> findCandidateAdvisors() {
  2. // super方法是解析传统的通过Advisor类实现的切面
  3. List<Advisor> advisors = super.findCandidateAdvisors();
  4. if (this.aspectJAdvisorsBuilder != null) {
  5. // 而这个方法,是通过@AspectJ方式来解析的切面
  6. advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
  7. }
  8. return advisors;
  9. }

super.findCandidateAdvisors()

Spring Transaction 就是通过这个方法,在容器中自己添加了一个Advisor来实现的。

  1. this.advisorRetrievalHelper.findAdvisorBeans();
  2. // 关键代码,找到容器中所有的Advisor 类型的bean
  3. String[] advisorNames = this.cachedAdvisorBeanNames;
  4. if (advisorNames == null) {
  5. advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);
  6. this.cachedAdvisorBeanNames = advisorNames;
  7. }

aspectJAdvisorsBuilder.buildAspectJAdvisors()

  1. // 部分代码
  2. public List<Advisor> buildAspectJAdvisors() {
  3. List<String> aspectNames = this.aspectBeanNames;
  4. if (aspectNames == null) {
  5. synchronized(this) {
  6. aspectNames = this.aspectBeanNames;
  7. if (aspectNames == null) {
  8. List<Advisor> advisors = new ArrayList();
  9. List<String> aspectNames = new ArrayList();
  10. // 找出所有的Object(即所有的bean)
  11. String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
  12. String[] var18 = beanNames;
  13. int var19 = beanNames.length;
  14. for(int var7 = 0; var7 < var19; ++var7) {
  15. String beanName = var18[var7];
  16. if (this.isEligibleBean(beanName)) {
  17. Class<?> beanType = this.beanFactory.getType(beanName);
  18. // 然后通过判断类上面是否标注了@AspectJ注解来判断是否要解析成一个切面,
  19. // 然后将@Before这些东西,解析成Advisor,注册到容器中
  20. if (beanType != null && this.advisorFactory.isAspect(beanType)) {
  21. aspectNames.add(beanName);
  22. AspectMetadata amd = new AspectMetadata(beanType, beanName);
  23. if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
  24. MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
  25. List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);

解析切面完成之后,就到了创建动态代理

wrapIfNecessary

  1. protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
  2. if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
  3. return bean;
  4. } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
  5. return bean;
  6. } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
  7. // 关键代码,用来找到符合这个Bean的切面
  8. Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
  9. if (specificInterceptors != DO_NOT_PROXY) {
  10. this.advisedBeans.put(cacheKey, Boolean.TRUE);
  11. Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
  12. this.proxyTypes.put(cacheKey, proxy.getClass());
  13. return proxy;
  14. } else {
  15. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  16. return bean;
  17. }
  18. } else {
  19. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  20. return bean;
  21. }
  22. }

getAdvicesAndAdvisorsForBean

  1. @Nullable
  2. protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
  3. List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
  4. return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray();
  5. }

findEligibleAdvisors

  1. protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
  2. List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
  3. // 找到可以应用的Advisor
  4. List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
  5. this.extendAdvisors(eligibleAdvisors);
  6. if (!eligibleAdvisors.isEmpty()) {
  7. eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
  8. }
  9. return eligibleAdvisors;
  10. }

findAdvisorsThatCanApply

  1. protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
  2. ProxyCreationContext.setCurrentProxiedBeanName(beanName);
  3. List var4;
  4. try {
  5. // 关键
  6. var4 = AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
  7. } finally {
  8. ProxyCreationContext.setCurrentProxiedBeanName((String)null);
  9. }
  10. return var4;
  11. }

调用Advisor中的pointCut,中的matches方法,进行切面的匹配

  1. public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
  2. if (advisor instanceof IntroductionAdvisor) {
  3. return ((IntroductionAdvisor)advisor).getClassFilter().matches(targetClass);
  4. } else if (advisor instanceof PointcutAdvisor) {
  5. PointcutAdvisor pca = (PointcutAdvisor)advisor;
  6. return canApply(pca.getPointcut(), targetClass, hasIntroductions);
  7. } else {
  8. return true;
  9. }
  10. }

所以,事务的切面匹配,也是这套流程,在 BeanFactoryTransactionAttributeSourceAdvisor,内部的pointCut类型为 TransactionAttributeSourcePointcut。

TransactionAttributeSourcePointcut#matches方法

  1. public boolean matches(Method method, Class<?> targetClass) {
  2. // 获取到的事务属性源,默认是 AnnotationTransactionAttributeSource
  3. TransactionAttributeSource tas = this.getTransactionAttributeSource();
  4. return tas == null || tas.getTransactionAttribute(method, targetClass) != null;
  5. }

AnnotationTransactionAttributeSource的继承图谱
image.png
所以,调用的getTransactionAttribute方法为 org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource中的getTransactionAttribute。(这里,就是最关键的Transactional的解析)

  1. @Nullable
  2. public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
  3. // 判断是不是Object类型,是的话,直接走
  4. if (method.getDeclaringClass() == Object.class) {
  5. return null;
  6. } else {
  7. Object cacheKey = this.getCacheKey(method, targetClass);
  8. TransactionAttribute cached = (TransactionAttribute)this.attributeCache.get(cacheKey);
  9. if (cached != null) {
  10. return cached == NULL_TRANSACTION_ATTRIBUTE ? null : cached;
  11. } else {
  12. // 查找@Transactional注解
  13. TransactionAttribute txAttr = this.computeTransactionAttribute(method, targetClass);
  14. // 找不到,放入一个默认的TransactionAttribute
  15. if (txAttr == null) {
  16. this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
  17. } else {
  18. String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
  19. if (txAttr instanceof DefaultTransactionAttribute) {
  20. ((DefaultTransactionAttribute)txAttr).setDescriptor(methodIdentification);
  21. }
  22. if (this.logger.isTraceEnabled()) {
  23. this.logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
  24. }
  25. this.attributeCache.put(cacheKey, txAttr);
  26. }
  27. return txAttr;
  28. }
  29. }
  30. }

最关键的代码

  1. @Nullable
  2. protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
  3. // 判断这个方法是不是public的,如果不是,调用不了,走了
  4. if (this.allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
  5. return null;
  6. } else {
  7. Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
  8. // 第一步,找目标类,看有没有注解,有了直接返回
  9. TransactionAttribute txAttr = this.findTransactionAttribute(specificMethod);
  10. if (txAttr != null) {
  11. return txAttr;
  12. } else {
  13. // 如果目标类没有,找实现类
  14. txAttr = this.findTransactionAttribute(specificMethod.getDeclaringClass());
  15. if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
  16. return txAttr;
  17. } else {
  18. if (specificMethod != method) {
  19. // 找实现类的接口方法
  20. txAttr = this.findTransactionAttribute(method);
  21. if (txAttr != null) {
  22. return txAttr;
  23. }
  24. // 找实现类的接口上
  25. txAttr = this.findTransactionAttribute(method.getDeclaringClass());
  26. if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
  27. return txAttr;
  28. }
  29. }
  30. return null;
  31. }
  32. }
  33. }
  34. }