前言
本篇接着上篇,对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(事务源码分析)