通过 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 类型的beanString[] 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
@Nullableprotected 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();// 找到可以应用的AdvisorList<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) {// 获取到的事务属性源,默认是 AnnotationTransactionAttributeSourceTransactionAttributeSource tas = this.getTransactionAttributeSource();return tas == null || tas.getTransactionAttribute(method, targetClass) != null;}
AnnotationTransactionAttributeSource的继承图谱
所以,调用的getTransactionAttribute方法为 org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource中的getTransactionAttribute。(这里,就是最关键的Transactional的解析)
@Nullablepublic 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);// 找不到,放入一个默认的TransactionAttributeif (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;}}}
最关键的代码
@Nullableprotected 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;}}}}
