基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。(四)

2014-11-24 07:23:37 · 作者: · 浏览: 3
ct proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
}
}
}

1.3、Spring使用AnnotationTransactionAttributeSource通过查找一个类或方法是否有@Transactional注解事务来返回TransactionAttribute(表示开启事务):

java代码:
package org.springframework.transaction.annotation;
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource implements Serializable {
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) {
for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae);
if (attr != null) {
return attr;
}
}
return null;
}
}

而AnnotationTransactionAttributeSource又使用SpringTransactionAnnotationParser来解析是否有@Transactional注解:

java代码:
package org.springframework.transaction.annotation;

public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {

public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {
Transactional ann = AnnotationUtils.getAnnotation(ae, Transactional.class);
if (ann != null) {
return parseTransactionAnnotation(ann);
}
else {
return null;
}
}

public TransactionAttribute parseTransactionAnnotation(Transactional ann) {

}

}

此处使用AnnotationUtils.getAnnotation(ae, Transactional.class); 这个方法只能发现当前方法/类上的注解,不能发现父类的注解。 Spring还提供了一个 AnnotationUtils.findAnnotation()方法 可以发现父类/父接口中的注解(但spring没有使用该接口)。

如果Spring此处换成AnnotationUtils.findAnnotation(),将可以发现父类/父接口中的注解。

这里还一个问题,描述如下:

在接口中删除@Transactional //开启默认事务

java代码:
package cn.javass.common.service;
public interface IBaseService {
public int countAll();
}

在具体类中添加@Transactional

java代码:
package cn.javass.common.service.impl;
public abstract class BaseService implements IBaseService {

@Transactional() //开启默认事务
@Override
public int countAll() {
return baseDao.countAll();
}
}


问题:

我们之前说过,基于JDK动态代理时, method 一定是接口上的method(因此放置在接口上的@Transactional是可以发现的),但现在我们放在具体类上,那么Spring是如何发现的呢??

还记得发现TransactionAttribute是通过AnnotationTransactionAttributeSource吗?具体看步骤1.3:

而AnnotationTransactionAttributeSource 继承AbstractFallbackTransactionAttributeSource

java代码:
package org.springframework.transaction.interceptor;
public abstract class AbstractFallbackTransactionAttributeSource implements TransactionAttributeSource {

public TransactionAttribute getTransactionAttribute(Method method, Class< > targetClass) {
//第一次 会委托给computeTransactionAttribute
}

//计算TransactionAttribute的
private TransactionAttribute computeTransactionAttribute(Method method, Class< > targetClass) {

//省略

// Ignore CGLIB subclasses - introspect the actual user class.
Class< > userClass = ClassUtils.getUserClass(targetClass);
// The method may be on an interface, but we need attributes from the target class.
// If the target class is null, the method will be unchanged.
//①此处将查找当前类覆盖的方法
Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);
// If we are dealing with method with generic parameters, find the original method.
specificMethod = BridgeMethodResolver.findBridgedMethod(specificM