spring源码之事务下篇

 

前言

本篇接着上篇,对TX的依赖注入的特殊处理进行分析。在之前,我们已经对AOP作了一个比较详细的分析,事务这块直接从AopUtils类的canApply方法进行分析。

依赖注入时的特殊处理

  • 这个方法我们在AOP分析时,已经到了这里但是没有继续分析下去。在事务这块,我们继续向下分析。首先我们看下如何拿到切点的pca.getPointcut()方法。我们知道在初始化时,注册了BeanFactoryTransactionAttributeSourceAdvisor类的BeanDefintion。

  而且我们在AOP中知道在获取所有advisor时,会实例化所有的advisor。所以,到这里,BeanFactoryTransactionAttributeSourceAdvisor实例化完成了,那么获取它的切点。

//AopUtils类的方法
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 { // It doesn't have a pointcut so we assume it applies. return true; } }
//BeanFactoryTransactionAttributeSourceAdvisor类的方法
//可以看到,这里用到之前初始化提到的AnnotationTransactionAttributeSource,创建了一个TransactionAttributeSourcePointcut的切点,后面会分析这个

private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
    @Override
    protected TransactionAttributeSource getTransactionAttributeSource() {
        return transactionAttributeSource;
    }
};

public Pointcut getPointcut() {
    return this.pointcut;
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
    Assert.notNull(pc, "Pointcut must not be null");
    if (!pc.getClassFilter().matches(targetClass)) {
        return false;
    }

    MethodMatcher methodMatcher = pc.getMethodMatcher();
    if (methodMatcher == MethodMatcher.TRUE) {
        // No need to iterate the methods if we're matching any method anyway...
        return true;
    }

    IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
    if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
        introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
    }

    Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
    classes.add(targetClass);
    for (Class<?> clazz : classes) {
        Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
        for (Method method : methods) {
            if ((introductionAwareMethodMatcher != null &&
                    introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
                    methodMatcher.matches(method, targetClass)) {
                return true;
            }
        }
    }

    return false;
}

总结

阅读完AOP,这块的代码还是简单的。下篇再接着对注入过程的进行源码分析

参考链接

  • https://www.cnblogs.com/zjstar12/archive/2012/06/17/2552710.html(jta分布式事务)
  • http://www.linkedkeeper.com/detail/blog.action?bid=1045(事务源码分析)

猜你喜欢

转载自www.cnblogs.com/lucas2/p/9338641.html