之前文章springAop原理之查找和原始bean关联的Advisor.已经分析了spring如何查找和判断Advisor是否和原始Bean关联,这里以 BeanFactoryTransactionAttributeSourceAdvisor(事务注解关联的Advisor)为例,具体分析下最后一个canApply方法。
ClassFilter
BeanFactoryTransactionAttributeSourceAdvisor的切点为TransactionAttributeSourcePointcut 继承了StaticMethodMatcherPointcut,StaticMethodMatcherPointcut对应的ClassFilter为TrueClassFilter,所以类匹配成功。
MethodMatcher
StaticMethodMatcherPointcut继承StaticMethodMatcher,所以TransactionAttributeSourcePointcut的MethodMatcher 为TransactionAttributeSourcePointcut自身。
TransactionAttributeSourcePointcut的matches源码
@Override
public boolean matches(Method method, Class<?> targetClass) {
if (TransactionalProxy.class.isAssignableFrom(targetClass) ||
PlatformTransactionManager.class.isAssignableFrom(targetClass) ||
PersistenceExceptionTranslator.class.isAssignableFrom(targetClass)) {
return false;
}
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
-
先判断TransactionalProxy、PlatformTransactionManager、PersistenceExceptionTranslator是否为当前class的父类,是的话返回false。一般都是false,自己写的sevice不会继承这些类。 -
获取TransactionAttributeSource。我们发现TransactionAttributeSourcePointcut其实是个抽象类,而TransactionAttributeSourcePointcut中的getTransactionAttributeSource也是一个抽象方法。从BeanFactoryTransactionAttributeSourceAdvisor源码,我们可以看到,BeanFactoryTransactionAttributeSourceAdvisor定义TransactionAttributeSourcePointcut时,已经重写了该方法
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
@Nullable
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};
返回的TransactionAttributeSource是BeanFactoryTransactionAttributeSourceAdvisor的一个成员变量。而BeanFactoryTransactionAttributeSourceAdvisor是spring通过@bean配置的(ProxyTransactionManagementConfiguration的transactionAdvisor()方法)
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource());
advisor.setAdvice(transactionInterceptor());
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
所以最终的TransactionAttributeSource为AnnotationTransactionAttributeSource。
- 最后由AnnotationTransactionAttributeSource调用getTransactionAttribute(method, targetClass)实际上是调用父类AbstractFallbackTransactionAttributeSource中的方法
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
if (method.getDeclaringClass() == Object.class) {
return null;
}
Object cacheKey = getCacheKey(method, targetClass);
TransactionAttribute cached = this.attributeCache.get(cacheKey);
if (cached != null) {
if (cached == NULL_TRANSACTION_ATTRIBUTE) {
return null;
}
else {
return cached;
}
}
else {
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
if (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 (logger.isTraceEnabled()) {
logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
}
this.attributeCache.put(cacheKey, txAttr);
}
return txAttr;
}
}
computeTransactionAttribute(method, targetClass)继续向下就会调用AnnotationTransactionAttributeSource中findTransactionAttribute(Method method)、findTransactionAttribute(Class<?> clazz),查找方法或类上是否有Transactional注解。
|