1.事务也是对方法的增强,所以最终也会创建代理对象;创建代理对象方法AbstractAutoProxyCreator.wrapIfNecessary;不熟悉的童鞋可以在Spring源码学习14、15、16、17回顾下;无论是通过tx:advice还是@Transaction注解方式实现事务,Spring最终都会将其封装为Advisor对象,可以看下AbstractAdvisorAutoProxyCreator.findCandidateAdvisors()方法的实现。
/**
* Find all eligible Advisor beans in the current bean factory,
* ignoring FactoryBeans and excluding beans that are currently in creation.
*
* 找到当前bean工厂中所有符合条件的Advisor bean,
* 忽略FactoryBeans并排除当前正在创建的bean。
* @return the list of {@link org.springframework.aop.Advisor} beans
* @see #isEligibleBean
*/
public List<Advisor> findAdvisorBeans() {
// 如果cachedAdvisorBeanNames尚未确定,则定advisor的beanName
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
//不要在这里初始化FactoryBeans:我们需要保留所有常规bean
//未初始化让自动代理创建者用于他们!
//事务其实是一种特殊的增强,属于环绕型增强所以使用了MethodInterceptor做增强实现
//通过tx:advice配置;最终通过<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
//配置一起将tx:advice和pointcut封装成DefaultBeanFactoryPointcutAdvisor
//所以这里能够获取到tx:advice配置的事务增强
//通过<tx:annotation-driven transaction-manager="transactionManager"/>
//配置实现的advisor最终为BeanFactoryTransactionAttributeSourceAdvisor
//所以该方法也能够获取到通过注解实现事务增强的advisor。
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<Advisor>();
}
List<Advisor> advisors = new ArrayList<Advisor>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
//创建advisor并添加到advisors集合;并实例化advisor
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
当上面执行完成后我们的用于实现事务的增强、切入点抽象出来的对象DefaultBeanFactoryPointcutAdvisor和BeanFactoryTransactionAttributeSourceAdvisor实例化
2.查找到所有事务抽象出来的advisor后,便需要去匹配符合当前被代理对象的advisor;
/**
* 确定适用于给定class的{@code candidateAdvisors}的子列表advisors
* @param candidateAdvisors the Advisors to evaluate
* @param clazz the target class
* @return sublist of Advisors that can apply to an object of the given class
* (may be the incoming List as-is)
*/
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
for (Advisor candidate : candidateAdvisors) {
//判断class是否符合IntroductionAdvisor的增强
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
//是否包含intructions,就是那个给代理类动态添加方法的
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
//实现事务增强的BeanFactoryTransactionAttributeSourceAdvisor和DefaultBeanFactoryPointcutAdvisor
//最终会通过该方法匹配 切入点
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
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;
}
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
//class不匹配直接退出
Assert.notNull(pc, "Pointcut must not be null");
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
//获取methodMatcher
MethodMatcher methodMatcher = pc.getMethodMatcher();
//为true直接返回true
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
//向上造型为IntroductionAwareMethodMatcher
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
//获取targetClass的所有classes包括父类
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;
}
我们通过tx:advice声明的事务,和普通的aop:advisor一样,最终会通过类似<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>,根据advisor的pointcut属性确定出匹配beanclass适用的advisor。
而通过注解实现事务,其匹配pointcut有所不同,我们可以先看下BeanFactoryTransactionAttributeSourceAdvisor的pointcut属性是怎么样的
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};
所以最后判断该advisor是否适用于当前beanclass最终实现在TransactionAttributeSourcePointcut.matches方法
@Override
public boolean matches(Method method, Class<?> targetClass) {
if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
return false;
}
//根据前文分析我们知道他的类型为AnnotationTransactionAttributeSource
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
3.AnnotationTransactionAttributeSource.getTransactionAttribute方法
/**
* 确定此方法调用的事务属性
* <p>如果未找到方法属性,则默认为类的事务属性.
* @param method the method for the current invocation (never {@code null})
* @param targetClass the target class for this invocation (may be {@code null})
* @return a TransactionAttribute for this method, or {@code null} if the method
* is not transactional
*/
@Override
public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) {
//object的method方法比如(equals clone等等),直接返回Null
if (method.getDeclaringClass() == Object.class) {
return null;
}
// First, see if we have a cached value.
// 我们先从缓存看看有没有
// MethodClassKey
Object cacheKey = getCacheKey(method, targetClass);
//缓存的TransactionAtrribute
TransactionAttribute cached = this.attributeCache.get(cacheKey);
//缓存存在
if (cached != null) {
// Value will either be canonical value indicating there is no transaction attribute,
// or an actual transaction attribute.
//值将是规范值,表示没有事务属性或实际事务属性。返回null
if (cached == NULL_TRANSACTION_ATTRIBUTE) {
return null;
}
else {
//返回缓存的TransactionAttribute
return cached;
}
}
else {
// We need to work it out.
// 获取txAttr属性好伐!
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
// 为null 放一个NULL_TRANSACTION_ATTRIBUTE
if (txAttr == null) {
this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
}
else {
//如果该targetClass的method方法有TransactionAttribute属性
//设置descriptor属性,不是我们关注的重点
String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
if (txAttr instanceof DefaultTransactionAttribute) {
((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
}
if (logger.isDebugEnabled()) {
logger.debug("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
}
//放入缓存
this.attributeCache.put(cacheKey, txAttr);
}
return txAttr;
}
}
真正获取TransationAttribute属性的方法在computeTransactionAttribute(method, targetClass)
/**
* 与{@link #getTransactionAttribute}相同的签名,但不缓存结果.
* {@link #getTransactionAttribute}实际上是此方法的缓存装饰器.
* <p>As of 4.1.8, this method can be overridden.
* @since 4.1.8
* @see #getTransactionAttribute
*/
protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
// 仅仅允许解析public方法的@Transaction 并且现在这个方法不是public;直接返回Null
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// 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(specificMethod);
// 首先查找target class 的method是否有txAttr
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
// Second try is the transaction attribute on the target class.
// 然后 尝试在target class上查找txAttr
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
// 如果存在接口;则去接口中找。哎嘿嘿
if (specificMethod != method) {
// Fallback is to look at the original method.
// 退回到原始方法中查找
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
// Last fallback is the class of the original method.
// 退回到原始的class中查找
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
return null;
}
我们根据方法可以看出实现查找@Transaction注解的属性的策略为:特定的目标方法>目标类>接口方法>声明类或者接口;依次查找直到找到返回。
4.findTransactionAttribute方法委托给了子类实现;AnnotationTransactionAttributeSource.determineTransactionAttribute
/**
* 确定给定方法或类的事务属性.
* <p>此实现委托配置
* {@link TransactionAnnotationParser TransactionAnnotationParsers}
* 用于将已知注释解析为Spring的元数据属性类.
* 如果它不是事务性的,则返回{@code null}.
* <p>可以重写以支持带有事务元数据的自定义注释
* @param element the annotated method or class
* @return the configured transaction attribute, or {@code null} if none was found
*/
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
if (element.getAnnotations().length > 0) {
for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
//委托解析工作给SpringTransactionAnnotationParser或者JtaTransactionAnnotationParser
//或者Ejb3TransactionAnnotationParser,这里我们只关心SpringTransactionAnnotationParser
TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
if (attr != null) {
return attr;
}
}
}
return null;
}
Spring给我们提供了三种annotationParsers;分别用于读取Spring的JDK 1.5+ {@link Transactional}注释,并向Spring的事务基础结构公开相应的事务属性 还支持JTA 1.2的{@link javax.transaction.Transactional}和EJB3的{@link javax.ejb.TransactionAttribute}注释(如果存在). 此类还可以作为自定义TransactionAttributeSource的基类,或通过{@link TransactionAnnotationParser}策略进行自定义.
5.SpringTransactionAnnotationParser.parseTransactionAnnotation
@Override
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
//提取@Transacation注解属性,并返回一个RuleBasedTransactionAttribute对象
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(
element, Transactional.class);
if (attributes != null) {
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
}
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
Propagation propagation = attributes.getEnum("propagation");
rbta.setPropagationBehavior(propagation.value());
Isolation isolation = attributes.getEnum("isolation");
rbta.setIsolationLevel(isolation.value());
rbta.setTimeout(attributes.getNumber("timeout").intValue());
rbta.setReadOnly(attributes.getBoolean("readOnly"));
rbta.setQualifier(attributes.getString("value"));
List<RollbackRuleAttribute> rollbackRules = new ArrayList<RollbackRuleAttribute>();
for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
rbta.setRollbackRules(rollbackRules);
return rbta;
}
上面的方法实现了对应类或者方法的事务属性解析。