溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

【原創(chuàng)】002 | 搭上SpringBoot事務(wù)源碼分析專(zhuān)車(chē)

發(fā)布時(shí)間:2020-06-22 08:05:35 來(lái)源:網(wǎng)絡(luò) 閱讀:332 作者:師長(zhǎng)學(xué)不動(dòng)了 欄目:編程語(yǔ)言

前言

如果這是你第二次看到師長(zhǎng),說(shuō)明你在覬覦我的美色!

點(diǎn)贊+關(guān)注再看,養(yǎng)成習(xí)慣

沒(méi)別的意思,就是需要你的窺屏^_^

專(zhuān)車(chē)介紹

該趟專(zhuān)車(chē)是開(kāi)往Spring Boot事務(wù)源碼分析的專(zhuān)車(chē)

專(zhuān)車(chē)問(wèn)題

  • 為什么加上@Transactional注解就可以實(shí)現(xiàn)事務(wù)?
  • 分析事務(wù)源碼之后我們可以學(xué)到什么?

專(zhuān)車(chē)名詞

事務(wù)

程序中通常使用事務(wù)來(lái)達(dá)到數(shù)據(jù)的一致性,從而避免臟數(shù)據(jù)

編程式事務(wù)

在業(yè)務(wù)方法開(kāi)頭開(kāi)啟事務(wù),然后對(duì)我們的業(yè)務(wù)進(jìn)行try-catch,假設(shè)沒(méi)有異常則提交事務(wù),如果出現(xiàn)異常,則在catch模塊回滾事務(wù)

聲明式事務(wù)由來(lái)

如果采用編程式事務(wù),那么在任何需要事務(wù)的地方都要開(kāi)啟事務(wù)、try-catch、提交或者回滾事務(wù),會(huì)導(dǎo)致重復(fù)編碼、編寫(xiě)與業(yè)務(wù)無(wú)關(guān)的代碼?;赟pring Aop思想,我們可以利用Aop的方式,對(duì)需要使用事務(wù)的方法進(jìn)行增強(qiáng),將公用的部分提取出來(lái),那么就實(shí)現(xiàn)了聲明式事務(wù)。

Spring提供的聲明式事務(wù)

在需要使用事務(wù)的業(yè)務(wù)方法上添加@Transactional注解,那么就可以使用事務(wù)的特性,要么成功,要么失敗

Spring Aop核心概念

  • 切面:切面是由切點(diǎn)和通知組成
  • 切點(diǎn):用來(lái)匹配符合條件類(lèi)或方法
  • 通知:需要執(zhí)行的操作

專(zhuān)車(chē)分析

基于Spring Boot自動(dòng)配置原理,我們應(yīng)該尋找xxxAutoConfiguration自動(dòng)配置類(lèi),此處要尋找和事務(wù)相關(guān)的,那么自然是TransactionAutoConfiguration

自動(dòng)配置

打開(kāi)TransactionAutoConfiguration自動(dòng)配置類(lèi)

@Configuration
@ConditionalOnBean(PlatformTransactionManager.class)
@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
public static class EnableTransactionManagementConfiguration {

    @Configuration
    @EnableTransactionManagement(proxyTargetClass = false)
    @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
    public static class JdkDynamicAutoProxyConfiguration {

    }

    @Configuration
    @EnableTransactionManagement(proxyTargetClass = true)
    @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
    public static class CglibAutoProxyConfiguration {

    }

}

可以看到開(kāi)啟事務(wù)管理器的注解@EnableTransactionManagement

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {}

查看TransactionManagementConfigurationSelector導(dǎo)入的類(lèi)

protected String[] selectImports(AdviceMode adviceMode) {
    switch (adviceMode) {
        case PROXY:
            return new String[] {AutoProxyRegistrar.class.getName(),
                    ProxyTransactionManagementConfiguration.class.getName()};
        case ASPECTJ:
            return new String[] {determineTransactionAspectClass()};
        default:
            return null;
    }
}

可以看到導(dǎo)入了AutoProxyRegistrar和ProxyTransactionManagementConfiguration

首先看看AutoProxyRegistrar,該類(lèi)實(shí)現(xiàn)了ImportBeanDefinitionRegistrar

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    boolean candidateFound = false;
    Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
    for (String annoType : annoTypes) {
        AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
        if (candidate == null) {
            continue;
        }
        Object mode = candidate.get("mode");
        Object proxyTargetClass = candidate.get("proxyTargetClass");
        if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
                Boolean.class == proxyTargetClass.getClass()) {
            candidateFound = true;
            if (mode == AdviceMode.PROXY) {
                // 注冊(cè)自動(dòng)代理創(chuàng)建器
                AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
                if ((Boolean) proxyTargetClass) {
                    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                    return;
                }
            }
        }
    }
}

注冊(cè)自動(dòng)代理創(chuàng)建器,AopConfigUtils#registerAutoProxyCreatorIfNecessary

public static BeanDefinition registerAutoProxyCreatorIfNecessary(
            BeanDefinitionRegistry registry, @Nullable Object source) {
    // 注冊(cè)了InfrastructureAdvisorAutoProxyCreator到IOC容器中
    return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}

InfrastructureAdvisorAutoProxyCreator是AbstractAutoProxyCreator的子類(lèi),AbstractAutoProxyCreator又實(shí)現(xiàn)了BeanPostProcessor接口,那么在bean初始化完畢后就會(huì)調(diào)用postProcessAfterInstantiation()方法,postProcessAfterInstantiation()定義在AbstractAutoProxyCreator類(lèi)中

BeanPostProcessor后置處理

打開(kāi)AbstractAutoProxyCreator

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            // 如果滿足條件對(duì)bean進(jìn)行包裹
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

該方法調(diào)用了wrapIfNecessary()方法

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    // Create proxy if we have advice.
    // 獲取bean的切面和通知
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    // 需要代理
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 創(chuàng)建代理
        Object proxy = createProxy(
                bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }

    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

根據(jù)注釋的意思就是如果存在advice,那么就創(chuàng)建代理,

尋找切面

進(jìn)入AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean

protected Object[] getAdvicesAndAdvisorsForBean(
            Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
    // 查找符合條件的切面
    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    // 不存在符合條件的切面,則不生成代理
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}

該代碼第一句最重要,如果不存在符合條件的切面,那么最終的結(jié)果返回null,根據(jù)上面分析的,如果為null就不創(chuàng)建代理,否則創(chuàng)建代理。接下來(lái)看看第一句的實(shí)現(xiàn)

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 獲取所有候選的切面,也就是類(lèi)型為Advisor的切面,此處獲取到的候選切面為BeanFactoryTransactionAttributeSourceAdvisor
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    // 從候選的切面中獲取可以解析當(dāng)前bean的切面,最終符合條件的切面為BeanFactoryTransactionAttributeSourceAdvisor
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

為什么上面獲取到的切面是BeanFactoryTransactionAttributeSourceAdvisor?是否還記得之前導(dǎo)入配置類(lèi)的時(shí)候還有一個(gè)配置類(lèi)沒(méi)有分析?那就是ProxyTransactionManagementConfiguration

打開(kāi)ProxyTransactionManagementConfiguration

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

    // 創(chuàng)建BeanFactoryTransactionAttributeSourceAdvisor
    @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
        BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
        advisor.setTransactionAttributeSource(transactionAttributeSource());
        // 設(shè)置切面對(duì)應(yīng)的通知,后面分析會(huì)用到
        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();
    }

    // 創(chuàng)建通知
    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public TransactionInterceptor transactionInterceptor() {
        TransactionInterceptor interceptor = new TransactionInterceptor();
        interceptor.setTransactionAttributeSource(transactionAttributeSource());
        if (this.txManager != null) {
            interceptor.setTransactionManager(this.txManager);
        }
        return interceptor;
    }

}

通過(guò)上面的自動(dòng)配置,可得知獲取到的候選切面為什么是BeanFactoryTransactionAttributeSourceAdvisor

接下來(lái)看看如何從候選切面中找到可以解析當(dāng)前bean的切面?

protected List<Advisor> findAdvisorsThatCanApply(
            List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

    ProxyCreationContext.setCurrentProxiedBeanName(beanName);
    try {
        // 查找可以解析當(dāng)前bean對(duì)應(yīng)的切面
        return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
    }
    finally {
        ProxyCreationContext.setCurrentProxiedBeanName(null);
    }
}

查找可以解析當(dāng)前bean對(duì)應(yīng)的切面,AopUtils#findAdvisorsThatCanApply

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
    if (candidateAdvisors.isEmpty()) {
        return candidateAdvisors;
    }
    List<Advisor> eligibleAdvisors = new ArrayList<>();
    for (Advisor candidate : candidateAdvisors) {
        if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
            eligibleAdvisors.add(candidate);
        }
    }
    boolean hasIntroductions = !eligibleAdvisors.isEmpty();
    for (Advisor candidate : candidateAdvisors) {
        if (candidate instanceof IntroductionAdvisor) {
            // already processed
            continue;
        }
        // 當(dāng)前切面是否可以解析bean
        if (canApply(candidate, clazz, hasIntroductions)) {
            eligibleAdvisors.add(candidate);
        }
    }
    return eligibleAdvisors;
}

候選切面是否可以解析bean

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) {
        // 由上面分析知道最終的候選切面為BeanFactoryTransactionAttributeSourceAdvisor
        // 該類(lèi)實(shí)現(xiàn)了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;
    }
}

候選切面是否可以解析bean

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;
    }

    // 獲取切面切點(diǎn)方法匹配對(duì)象,用來(lái)匹配方法是否符合
    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<>();
    if (!Proxy.isProxyClass(targetClass)) {
        classes.add(ClassUtils.getUserClass(targetClass));
    }
    classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

    for (Class<?> clazz : classes) {
        // 通過(guò)反射獲取當(dāng)前類(lèi)所有的Method對(duì)象
        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;
}

匹配方法TransactionAttributeSourcePointcut#matches

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();
    // 如果事務(wù)屬性源對(duì)象為空或者事務(wù)屬性對(duì)象不為null返回true,代表匹配成功;否則返回false,匹配失敗
    return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

獲取事務(wù)屬性對(duì)象,AbstractFallbackTransactionAttributeSource#getTransactionAttribute

public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
    if (method.getDeclaringClass() == Object.class) {
        return null;
    }

    // First, see if we have a cached value.
    Object cacheKey = getCacheKey(method, targetClass);
    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.
        if (cached == NULL_TRANSACTION_ATTRIBUTE) {
            return null;
        }
        else {
            return cached;
        }
    }
    else {
        // 計(jì)算事務(wù)屬性對(duì)象
        TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
        // Put it in the cache.
        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;
    }
}

計(jì)算事務(wù)屬性對(duì)象

protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
    // Don't allow no-public methods as required.
    if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
        return null;
    }

    // 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 = AopUtils.getMostSpecificMethod(method, targetClass);

    // First try is the method in the target class.
    // 首先根據(jù)Method對(duì)象獲取事務(wù)屬性對(duì)象
    TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
    if (txAttr != null) {
        return txAttr;
    }

    // Second try is the transaction attribute on the target class.
    // 如果根據(jù)Method對(duì)象獲取不到事務(wù)屬性對(duì)象,那么根據(jù)Class來(lái)獲取屬性對(duì)象
    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.
        txAttr = findTransactionAttribute(method.getDeclaringClass());
        if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
            return txAttr;
        }
    }

    return null;
}

獲取屬性對(duì)象AnnotationTransactionAttributeSource#findTransactionAttribute

protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
    return determineTransactionAttribute(clazz);
}

決定事務(wù)屬性對(duì)象

protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
    for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
        TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
        if (attr != null) {
            return attr;
        }
    }
    return null;
}

解析事務(wù)屬性對(duì)象,SpringTransactionAnnotationParser#parseTransactionAnnotation

public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
    // 判斷元素是否含有@Transactional注解,通過(guò)前面的分析我們可以得出如下結(jié)論:
    // 1、首選判斷類(lèi)的方法上是否含有@Transactional注解,如果有就解析
    // 2、如果所有的方法都不含有@Transactional注解,那么判斷當(dāng)前類(lèi)是否含有@Transactional注解,如果有就解析
    // 3、如果類(lèi)或者類(lèi)的某個(gè)方法含有@Transactional注解,那么事務(wù)屬性對(duì)象就不為空,則說(shuō)明次切面可以解析當(dāng)前bean
    AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
            element, Transactional.class, false, false);
    if (attributes != null) {
        return parseTransactionAnnotation(attributes);
    }
    else {
        return null;
    }
}

回到AbstractAutoProxyCreator#wrapIfNecessary

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // Create proxy if we have advice.
    // 此處有值返回,進(jìn)行代理,否則不進(jìn)行代理
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    // 需要進(jìn)行代理
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 創(chuàng)建代理
        Object proxy = createProxy(
                bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }

    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

創(chuàng)建代理

創(chuàng)建代理AbstractAutoProxyCreator#createProxy

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
            @Nullable Object[] specificInterceptors, TargetSource targetSource) {

    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    }

    // 創(chuàng)建代理工廠
    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.copyFrom(this);

    if (!proxyFactory.isProxyTargetClass()) {
        if (shouldProxyTargetClass(beanClass, beanName)) {
            proxyFactory.setProxyTargetClass(true);
        }
        else {
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }

    // 構(gòu)建切面,此處的切面為BeanFactoryTransactionAttributeSourceAdvisor
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    // 設(shè)置切面
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    customizeProxyFactory(proxyFactory);

    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }

    return proxyFactory.getProxy(getProxyClassLoader());
}

獲取代理ProxyFactory#getProxy

public Object getProxy(@Nullable ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
}

創(chuàng)建aop代理

protected final synchronized AopProxy createAopProxy() {
    if (!this.active) {
        activate();
    }
    // 此處的this實(shí)際上就是ProxyFactory
    return getAopProxyFactory().createAopProxy(this);
}

aop代理工廠創(chuàng)建aop代理DefaultAopProxyFactory#createAopProxy

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        Class<?> targetClass = config.getTargetClass();
        if (targetClass == null) {
            throw new AopConfigException("TargetSource cannot determine target class: " +
                    "Either an interface or a target is required for proxy creation.");
        }
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        // 創(chuàng)建cglib aop代理
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        return new JdkDynamicAopProxy(config);
    }
}

實(shí)例化ObjenesisCglibAopProxy對(duì)象

public ObjenesisCglibAopProxy(AdvisedSupport config) {
    super(config);
}

父類(lèi)實(shí)例化

public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
    Assert.notNull(config, "AdvisedSupport must not be null");
    if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
        throw new AopConfigException("No advisors and no TargetSource specified");
    }
    // 此處的config就是之前的ProxyFactory
    this.advised = config;
    this.advisedDispatcher = new AdvisedDispatcher(this.advised);
}

回到之前獲取代理的地方

public Object getProxy(@Nullable ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
}

通過(guò)上面的分析可以得知createAopProxy()返回的是CglibAopProxy

通過(guò)CglibAopProxy獲取代理,CglibAopProxy#getProxy

public Object getProxy(@Nullable ClassLoader classLoader) {
    if (logger.isTraceEnabled()) {
        logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
    }

    try {
        Class<?> rootClass = this.advised.getTargetClass();
        Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

        Class<?> proxySuperClass = rootClass;
        if (ClassUtils.isCglibProxyClass(rootClass)) {
            proxySuperClass = rootClass.getSuperclass();
            Class<?>[] additionalInterfaces = rootClass.getInterfaces();
            for (Class<?> additionalInterface : additionalInterfaces) {
                this.advised.addInterface(additionalInterface);
            }
        }

        // Validate the class, writing log messages as necessary.
        validateClassIfNecessary(proxySuperClass, classLoader);

        // Configure CGLIB Enhancer...
        // 創(chuàng)建Enhancer對(duì)象
        Enhancer enhancer = createEnhancer();
        if (classLoader != null) {
            enhancer.setClassLoader(classLoader);
            if (classLoader instanceof SmartClassLoader &&
                    ((SmartClassLoader) classLoader).isCla***eloadable(proxySuperClass)) {
                enhancer.setUseCache(false);
            }
        }
        // 設(shè)置父類(lèi)
        enhancer.setSuperclass(proxySuperClass);
        // 設(shè)置接口
        enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
        enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
        enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

        // 獲取回調(diào),重點(diǎn)分析
        Callback[] callbacks = getCallbacks(rootClass);
        Class<?>[] types = new Class<?>[callbacks.length];
        for (int x = 0; x < types.length; x++) {
            types[x] = callbacks[x].getClass();
        }
        // fixedInterceptorMap only populated at this point, after getCallbacks call above
        enhancer.setCallbackFilter(new ProxyCallbackFilter(
                this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
        // 設(shè)置回調(diào)類(lèi)型
        enhancer.setCallbackTypes(types);

        // Generate the proxy class and create a proxy instance.
        // 生成代理并創(chuàng)建代理實(shí)例
        return createProxyClassAndInstance(enhancer, callbacks);
    }
    catch (CodeGenerationException | IllegalArgumentException ex) {
        throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
                ": Common causes of this problem include using a final class or a non-visible class",
                ex);
    }
    catch (Throwable ex) {
        // TargetSource.getTarget() failed
        throw new AopConfigException("Unexpected AOP exception", ex);
    }
}

獲取回調(diào)

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
    // Parameters used for optimization choices...
    boolean exposeProxy = this.advised.isExposeProxy();
    boolean isFrozen = this.advised.isFrozen();
    boolean isStatic = this.advised.getTargetSource().isStatic();

    // Choose an "aop" interceptor (used for AOP calls).
    // 實(shí)例化回調(diào),在調(diào)用目標(biāo)對(duì)象方法的時(shí)候執(zhí)行
    Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
    return callbacks;
}

實(shí)例化回調(diào)部分

private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {

    private final AdvisedSupport advised;

    public DynamicAdvisedInterceptor(AdvisedSupport advised) {
        // 設(shè)置切面信息,也就是之前的ProxyFactory
        this.advised = advised;
    }

    @Override
    @Nullable
    // 調(diào)用目標(biāo)方法的時(shí)候執(zhí)行
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object oldProxy = null;
        boolean setProxyContext = false;
        Object target = null;
        TargetSource targetSource = this.advised.getTargetSource();
        try {
            if (this.advised.exposeProxy) {
                // Make invocation available if necessary.
                oldProxy = AopContext.setCurrentProxy(proxy);
                setProxyContext = true;
            }
            // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
            target = targetSource.getTarget();
            Class<?> targetClass = (target != null ? target.getClass() : null);
            // 獲取通知,此處的通知為T(mén)ransactionInterceptor
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            Object retVal;
            // Check whether we only have one InvokerInterceptor: that is,
            // no real advice, but just reflective invocation of the target.
            if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                // We can skip creating a MethodInvocation: just invoke the target directly.
                // Note that the final invoker must be an InvokerInterceptor, so we know
                // it does nothing but a reflective operation on the target, and no hot
                // swapping or fancy proxying.
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = methodProxy.invoke(target, argsToUse);
            }
            else {
                // We need to create a method invocation...
                retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
            }
            retVal = proce***eturnType(proxy, target, method, retVal);
            return retVal;
        }
        finally {
            if (target != null && !targetSource.isStatic()) {
                targetSource.releaseTarget(target);
            }
            if (setProxyContext) {
                // Restore old proxy.
                AopContext.setCurrentProxy(oldProxy);
            }
        }
    }

    @Override
    public boolean equals(Object other) {
        return (this == other ||
                (other instanceof DynamicAdvisedInterceptor &&
                        this.advised.equals(((DynamicAdvisedInterceptor) other).advised)));
    }

    /**
     * CGLIB uses this to drive proxy creation.
     */
    @Override
    public int hashCode() {
        return this.advised.hashCode();
    }
}

調(diào)用invocation的處理方法,ReflectiveMethodInvocation#proceed

public Object proceed() throws Throwable {
    //  We start with an index of -1 and increment early.
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        return invokeJoinpoint();
    }

    // 此處的通知TransactionInterceptor
    Object interceptorOrInterceptionAdvice =
            this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
        // Evaluate dynamic method matcher here: static part will already have
        // been evaluated and found to match.
        InterceptorAndDynamicMethodMatcher dm =
                (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
        Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
        if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
            return dm.interceptor.invoke(this);
        }
        else {
            // Dynamic matching failed.
            // Skip this interceptor and invoke the next in the chain.
            return proceed();
        }
    }
    else {
        // It's an interceptor, so we just invoke it: The pointcut will have
        // been evaluated statically before this object was constructed.
        // 調(diào)用TransactionInterceptor#invoke
        return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    }
}

調(diào)用TransactionInterceptor#invoke

public Object invoke(MethodInvocation invocation) throws Throwable {
    // Work out the target class: may be {@code null}.
    // The TransactionAttributeSource should be passed the target class
    // as well as the method, which may be from an interface.
    Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

    // Adapt to TransactionAspectSupport's invokeWithinTransaction...
    // 以事務(wù)的方式進(jìn)行調(diào)用
    return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}

事務(wù)方式調(diào)用

protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
            final InvocationCallback invocation) throws Throwable {

    // If the transaction attribute is null, the method is non-transactional.
    TransactionAttributeSource tas = getTransactionAttributeSource();
    final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
    final PlatformTransactionManager tm = determineTransactionManager(txAttr);
    final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

    if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
        // Standard transaction demarcation with getTransaction and commit/rollback calls.
        // 創(chuàng)建事務(wù)信息對(duì)象
        TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
        Object retVal = null;
        try {
            // This is an around advice: Invoke the next interceptor in the chain.
            // This will normally result in a target object being invoked.
            // 調(diào)用被代理對(duì)象方法
            retVal = invocation.proceedWithInvocation();
        }
        catch (Throwable ex) {
            // target invocation exception
            // 業(yè)務(wù)方法執(zhí)行異常,進(jìn)行事務(wù)回滾
            completeTransactionAfterThrowing(txInfo, ex);
            throw ex;
        }
        finally {
            // 清除事務(wù)信息對(duì)象
            cleanupTransactionInfo(txInfo);
        }
        // 提交事務(wù)
        commitTransactionAfterReturning(txInfo);
        return retVal;
    }

    else {
        final ThrowableHolder throwableHolder = new ThrowableHolder();

        // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
        try {
            Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
                TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
                try {
                    return invocation.proceedWithInvocation();
                }
                catch (Throwable ex) {
                    if (txAttr.rollbackOn(ex)) {
                        // A RuntimeException: will lead to a rollback.
                        if (ex instanceof RuntimeException) {
                            throw (RuntimeException) ex;
                        }
                        else {
                            throw new ThrowableHolderException(ex);
                        }
                    }
                    else {
                        // A normal return value: will lead to a commit.
                        throwableHolder.throwable = ex;
                        return null;
                    }
                }
                finally {
                    cleanupTransactionInfo(txInfo);
                }
            });

            // Check result state: It might indicate a Throwable to rethrow.
            if (throwableHolder.throwable != null) {
                throw throwableHolder.throwable;
            }
            return result;
        }
        catch (ThrowableHolderException ex) {
            throw ex.getCause();
        }
        catch (TransactionSystemException ex2) {
            if (throwableHolder.throwable != null) {
                logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
                ex2.initApplicationException(throwableHolder.throwable);
            }
            throw ex2;
        }
        catch (Throwable ex2) {
            if (throwableHolder.throwable != null) {
                logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
            }
            throw ex2;
        }
    }
}

到此事務(wù)的源碼分析就結(jié)束了

專(zhuān)車(chē)總結(jié)

  • 導(dǎo)入AutoProxyRegistrar、ProxyTransactionManagementConfiguration配置類(lèi)
  • AutoProxyRegistrar用來(lái)注冊(cè)InfrastructureAdvisorAutoProxyCreator到IOC中,InfrastructureAdvisorAutoProxyCreator實(shí)現(xiàn)了BeanPostProcessor
  • 執(zhí)行BeanPostProcessor的后置處理
  • 獲取由ProxyTransactionManagementConfiguration配置類(lèi)創(chuàng)建的切面
  • 通過(guò)切面解析bean是否需要?jiǎng)?chuàng)建代理,需要就創(chuàng)建代理
  • 執(zhí)行代理的回調(diào),在回調(diào)中拿到通知
  • 執(zhí)行通知,通知里面邏輯:開(kāi)啟事務(wù)、執(zhí)行目標(biāo)方法、提交或回滾事務(wù)

專(zhuān)車(chē)回顧

回顧下開(kāi)頭的兩個(gè)問(wèn)題:

  • 為什么加上@Transactional注解就可以實(shí)現(xiàn)事務(wù)?
  • 分析事務(wù)源碼之后我們可以學(xué)到什么?

通過(guò)以上分析,第一個(gè)問(wèn)題應(yīng)該就迎刃而解了,那么通過(guò)以上學(xué)到的知識(shí)我們可以實(shí)現(xiàn)什么功能呢?在下一篇我們會(huì)在此基礎(chǔ)上進(jìn)行實(shí)戰(zhàn),通過(guò)@SystemLog注解實(shí)現(xiàn)系統(tǒng)日志功能。感謝各位擼友乘坐此趟專(zhuān)車(chē),歡迎下次繼續(xù)乘坐

最后

師長(zhǎng),專(zhuān)注分享Java進(jìn)階、架構(gòu)技術(shù)、高并發(fā)、微服務(wù)、BAT面試、redis專(zhuān)題、JVM調(diào)優(yōu)、Springboot源碼、mysql優(yōu)化等20大進(jìn)階架構(gòu)專(zhuān)題。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI