springboot 事務創建流程源碼分析

springboot 事務創建流程源碼分析

springboot中事務是相對重要的一個部分。也是aop的一個使用場景。我們今天就來一起從源碼的角度分析下,事務的整個創建過程。

關於springboot啟動過程中的一些加載,很多都是通用的,這塊就不再仔細講述了。這部分可以參看spring boot 加載web容器tomcat流程源碼分析springboot整合mybatis源碼分析這兩篇文章

關於enhancer生成代理類的過程,可以參看Springboot中註解@Configuration源碼分析

代碼路徑:springboot-transaction

1. 自動加載配置

首先還是讀取org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration這個配置類,

方式還是通過springboot啟動的時候自動加載配置文件spring-boot-autoconfigure-2.5.2.jar中\META-INF\spring.factories這個文件中key=org.springframework.boot.autoconfigure.EnableAutoConfiguration的值。其中就有org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration這個類。

在加載org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration時,會掃描加載內部類。

這裡就會掃描到EnableTransactionManagementConfiguration這個內部類。


	@Configuration(proxyBeanMethods = false)
	@ConditionalOnBean(TransactionManager.class)
	@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
	public static class EnableTransactionManagementConfiguration {
		
		@Configuration(proxyBeanMethods = false)
		@EnableTransactionManagement(proxyTargetClass = false)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false")
		public static class JdkDynamicAutoProxyConfiguration {

		}

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

		}

	}

同時會掃描JdkDynamicAutoProxyConfiguration,CglibAutoProxyConfiguration這兩個類,默認,我們在上下文中沒有配置spring.aop.proxy-target-class屬性,所以就只會加載CglibAutoProxyConfiguration這個類,繼而讀取@EnableTransactionManagement(proxyTargetClass = true)註解,繼續去加載EnableTransactionManagement註解類上的import註解。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
//會讀取這裡的import註解,去加載TransactionManagementConfigurationSelector這個類
public @interface EnableTransactionManagement {
	......
}

我們看下這個TransactionManagementConfigurationSelector的繼承關係

可以看到TransactionManagementConfigurationSelector繼承了AdviceModeImportSelector這個,間接實現了ImportSelector接口,所以在加載TransactionManagementConfigurationSelector時,會調用ImportSelector接口的這個方法String[] selectImports(AnnotationMetadata importingClassMetadata);這個接口,這個接口當前時在AdviceModeImportSelector這個類中實現的。

我們看看這部分代碼

	//這個代碼在AdviceModeImportSelector類中
	public final String[] selectImports(AnnotationMetadata importingClassMetadata) {
		Class<?> annType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class);
        //這句代碼是獲取AdviceModeImportSelector子類的泛型參數。我們這裡獲取到的是EnableTransactionManagement
        
		Assert.state(annType != null, "Unresolvable type argument for AdviceModeImportSelector");

		AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
        //這句是從當前類的導入類中獲取泛型參數註解的對象,這裡獲取到的是CglibAutoProxyConfiguration類上@EnableTransactionManagement(proxyTargetClass = true)註解的值
        
		if (attributes == null) {
			throw new IllegalArgumentException(String.format(
					"@%s is not present on importing class '%s' as expected",
					annType.getSimpleName(), importingClassMetadata.getClassName()));
		}

		AdviceMode adviceMode = attributes.getEnum(getAdviceModeAttributeName());
        //這個是獲取model屬性的值,這個屬性有默認值EnableTransactionManagement註解mode的默認值是AdviceMode.PROXY
        
		String[] imports = selectImports(adviceMode);
        //這個代碼的實現在TransactionManagementConfigurationSelector類中,這個也比較簡單,就是根據adviceMode的值,返回要加載的類的類名,當前這裡返回的是new String[] {AutoProxyRegistrar.class.getName(),						ProxyTransactionManagementConfiguration.class.getName()};
        //後面就會去加載AutoProxyRegistrar和ProxyTransactionManagementConfiguration這兩個類
        
		if (imports == null) {
			throw new IllegalArgumentException("Unknown AdviceMode: " + adviceMode);
		}
		return imports;
	}

下面我們看看AutoProxyRegistrar和ProxyTransactionManagementConfiguration這兩個類的加載

AutoProxyRegistrar實現了ImportBeanDefinitionRegistrar接口,加載時就會調用registerBeanDefinitions。

	//AutoProxyRegistrar的方法
	//這裡的importingClassMetadata可以認為還是CglibAutoProxyConfiguration
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		boolean candidateFound = false;
		Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
        //這裡是獲取CglibAutoProxyConfiguration類上的註解
        
        //這裡就比較簡單了,依次獲取CglibAutoProxyConfiguration類上的註解,查看屬性mode和proxyTargetClass
		for (String annType : annTypes) {
			AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
			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) {
                    //最終會走到這裡
					AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
                    //這裡就不進去了,這個會在registry中添加InfrastructureAdvisorAutoProxyCreator.class這個類的beanDefinition
                    
					if ((Boolean) proxyTargetClass) {
						AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                        //這裡是添加了屬性("proxyTargetClass", Boolean.TRUE),最終生成的InfrastructureAdvisorAutoProxyCreator的屬性進行設置
						return;
					}
				}
			}
		}
		......
	}

ProxyTransactionManagementConfiguration這個類是一個普通的Configuration配置類,在加載它的過程中同樣會掃描到它裏面的beanmethod進行加載,這裏面的幾個也都比較重要,我們看看它的源碼

@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
//會掃描它內部的beanMethod,進行加載,關於這beanmethod的所用,這裡就不展看說了,具體在講解到事務執行流程的時候再說吧
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    //注意:這個方法的兩個入參是後面兩個beanmethod方法的bean對象
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
			TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {

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

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    //這個主要就是事務攔截器,事務相關的就會交給它去處理
	public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
		TransactionInterceptor interceptor = new TransactionInterceptor();
		interceptor.setTransactionAttributeSource(transactionAttributeSource);
		if (this.txManager != null) {
			interceptor.setTransactionManager(this.txManager);
		}
		return interceptor;
	}

}

到這裡,我們看看主要加載的bean都有哪些

  • InfrastructureAdvisorAutoProxyCreator,BeanFactoryTransactionAttributeSourceAdvisor主要是這兩個

    TransactionAttributeSource,TransactionInterceptor這兩個注入到了BeanFactoryTransactionAttributeSourceAdvisor這個對象中,就不單獨說了,應該可以通過BeanFactoryTransactionAttributeSourceAdvisor這個bean對象獲取到

2. InfrastructureAdvisorAutoProxyCreator類

我們看看InfrastructureAdvisorAutoProxyCreator的繼承關係

這個類的繼承關係是比較複雜的,我們只挑選我們最關注的來分析吧。

從圖上可以看到InfrastructureAdvisorAutoProxyCreator類間接實現了BeanPostProcessor接口,這個接口主要的所用是對每一個bean對象初始化前後做增強。在每一個bean初始化前調用postProcessBeforeInitialization,初始化後調用postProcessAfterInitialization。

注意:這裡說的bean初始化前後並不是創建對象前後,這些操作肯定都是在創建對象之後

3.BeanFactoryTransactionAttributeSourceAdvisor類

​ 我們現在看看BeanFactoryTransactionAttributeSourceAdvisor類,首先看下它的繼承關係

可以看到這個類也實現了Advisor接口,這個接口主要是用來承載Advice,而Advice主要是用來執行作為攔截器來使用的。

同時這個類也實現了PointcutAdvisor,可以返回Pointcut,可以用來篩選哪些方法需要攔截

4.判斷bean對象是否需要進行事務增強處理

bean初始化後也會調用到InfrastructureAdvisorAutoProxyCreator.postProcessAfterInitialization方法(在AbstractAutoProxyCreator這個類中)。繼而會調用到wrapIfNecessary這個方法。我們去看看這個方法

	//AbstractAutoProxyCreator類中的方法
	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.
        //看上面的英文注釋也能簡單明白 aop就是在這裡生成的,對應事務其實也是用aop來完成的,我們重點看看這裡的代碼。
        //我們的@Transactional註解是在UserServiceImpl這個類上,所以我們就只關注這個類的執行過程就可以了,我們進到這個方法裏面去看看
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        //這個specificInterceptors主要是Advisor,這個不為空,說明當前的bean對象,可以被specificInterceptors來進行aop代理,就會進入裏面的createProxy進行aop增強
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
            //在這裡會生成代理類,並返回代理對象
			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;
	}
@Override
@Nullable
//這個方法主要是根據我們傳入的bean,查找適用的advice和advisor,如果返回的是空,就說明不需要進行AOP增強,
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();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   //這句比較簡單,主要就是在beanFactory中獲取類型是Advisor.class的對應bean,這個也比較簡單,就跳進去看了,
   //我們這裡會返回的List中就會只有org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   
   //這個主要是根據我們傳入的bean對象,從candidateAdvisors返回合適的advisor,我們走進去看看
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
   extendAdvisors(eligibleAdvisors);
   if (!eligibleAdvisors.isEmpty()) {
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}
	public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
		if (candidateAdvisors.isEmpty()) {
			return candidateAdvisors;
		}
		List<Advisor> eligibleAdvisors = new ArrayList<>();
		for (Advisor candidate : candidateAdvisors) {
            //我們當前傳入的BeanFactoryTransactionAttributeSourceAdvisor不是IntroductionAdvisor接口的實現,不會走到這裡
			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;
			}
            //真正起所用的是在這裡,我們繼續跳進去看看
            //canApply返回true,就說明當前的candidate能作用於當前clazz,就需要加到列表,後續生成aop代理的時候需要
			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 主要是通過getPointcut來獲取Pointcut,從目標類上尋找應該被進行aop增強的類和方法
      PointcutAdvisor pca = (PointcutAdvisor) advisor;
      //會走到這裏面,我們繼續進去看看,在這裡就是去查找對應類的事務屬性(簡單來說就是獲取方法上的@Transactional的相關屬性),如果能獲取到這裡就會返回true,獲取不到就會返回false 
      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) {
		Assert.notNull(pc, "Pointcut must not be null");
        
        //這個主要是判斷類是否有必要pointcut的匹配。
        //1. 如果類是TransactionalProxy、TransactionManager、PersistenceExceptionTranslator那就不需要後續匹配了直接從if分支裏面返回
        //2.或者要找的類是java.開頭的,或者org.springframework.core這個接口,也從這裡返回  
        //我們當前查找的是事務的註解,名字是org.springframework.transaction.annotation.Transactional
        //我們當前要匹配的類是com.springboot.transaction.service.impl.UserServiceImpl
        //上面兩個條件都不匹配,所以不會進入這個分支,繼續向下走
		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<>();
		if (!Proxy.isProxyClass(targetClass)) {
            //會走到這裡,將com.springboot.transaction.service.impl.UserServiceImpl加入到classes中
			classes.add(ClassUtils.getUserClass(targetClass));
		}
        //在這裡會將當前類實現的接口com.springboot.transaction.service.UserService也加入進來
		classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
		
        //在下面這裡就會去遍歷類上的所有方法,查找是否有  @Transactional註解
		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;
	}
//這個方法在TransactionAttributeSourcePointcut,這是一個抽象類
//當前這個類是BeanFactoryTransactionAttributeSourceAdvisor中的內部匿名類,類實例對象名是pointcut
	@Override
	public boolean matches(Method method, Class<?> targetClass) {
        //這個tas就是在初始化BeanFactoryTransactionAttributeSourceAdvisor這個bean時,注入上去的TransactionAttributeSource的bean
		TransactionAttributeSource tas = getTransactionAttributeSource();
		return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
	}
//這個方法在AbstractFallbackTransactionAttributeSource,
//注入上去的TransactionAttributeSource的bean的實際類型是AnnotationTransactionAttributeSource,它繼承了AbstractFallbackTransactionAttributeSource
@Override
@Nullable
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
   if (method.getDeclaringClass() == Object.class) {
      return null;
   }

   // First, see if we have a cached value.
    //在這裡會生成一個緩存的key
   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 {
      // We need to work it out.
      //在這就是在對應的method上去查看是否有對應Transactional註解,如果有,就封裝成TransactionAttribute返回
      //這個具體也是通過SpringTransactionAnnotationParser.parseTransactionAnnotation方法來完成的,這個比較簡單,就不進去了
      TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
      // Put it in the cache.
      if (txAttr == null) {
         //如果獲取不到,為了避免後續重複查找,也會在這裡添加緩存 
         this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
      }
      else {
         //我們當前會走到這裡,methodIdentification就是類名加方法名的拼接,作為描述
         String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
         if (txAttr instanceof DefaultTransactionAttribute) {
            DefaultTransactionAttribute dta = (DefaultTransactionAttribute) txAttr;
            dta.setDescriptor(methodIdentification);
            dta.resolveAttributeStrings(this.embeddedValueResolver);
         }
         if (logger.isTraceEnabled()) {
            logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
         }
         //在這裡將解析出來的 TransactionAttribute添加到緩存中並返回
         this.attributeCache.put(cacheKey, txAttr);
      }
      return txAttr;
   }
}

上面的事務屬性TransactionAttribute不為空,就說明當前類可以被用來生成aop代理,進行事務的增強處理。就會調用

Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

來生成對應的代理類,來進行事務處理。

5.生成對應代理類

我們進入createProxy方法去看看代理類的生成過程

//這個方法在AbstractAutoProxyCreator
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);
		}
		//這個是代理類的工程,下面主要是設置一些屬性,會在方法的最後一行proxyFactory.getProxy(classLoader);生成代理對象,我們直接進去看看
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);

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

		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

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

		// Use original ClassLoader if bean class not locally loaded in overriding class loader
		ClassLoader classLoader = getProxyClassLoader();
		if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
			classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
		}
		return proxyFactory.getProxy(classLoader);
	}
	public Object getProxy(@Nullable ClassLoader classLoader) {
        //先創建對應類的代理類,然後使用代理類生成代理對象
		return createAopProxy().getProxy(classLoader);
	}

	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		//在這會調用實際工廠DefaultAopProxyFactory去生成代理類
		return getAopProxyFactory().createAopProxy(this);
	}

	//這個方法在DefaultAopProxyFactory
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (!NativeDetector.inNativeImage() &&
				(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.");
			}
            //如果是一個接口,或者是一個proxy類,就會都java的動態代理
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
            //其他的就會走到這裡
            //我們當前的是com.springboot.transaction.service.impl.UserServiceImpl就會走到這裡
            //到這裡代理類就生成了,後續就會用這個去生成我們需要的代理對象
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}
//這個方法在CglibAopProxy,具體生成代理類也會是在這裡
	@Override
	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 (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
				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...
            //具體創建代理類就用的是Enhancer,這和Configuration具體是差不多的,裏面一些細節就去不進行看了
            //具體的做法還是在enhancer上設置屬性,最終調用asm,動態生成位元組碼,加載到jvm,生成新的代理class對象,並創建代理類對象
			Enhancer enhancer = createEnhancer();
			if (classLoader != null) {
                //這裡設置classLoader,最終把生成的class加載到jvm時需要
				enhancer.setClassLoader(classLoader);
				if (classLoader instanceof SmartClassLoader &&
						((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
					enhancer.setUseCache(false);
				}
			}
            //這裡設置最終生成代理類的父類com.springboot.transaction.service.impl.UserServiceImpl
			enhancer.setSuperclass(proxySuperClass);
            //這個是設置最終生成代理類要實現的接口,(SpringProxy.class,Advised.class).我們後面會去看看這個方法
			enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
            //這個是設置代理類名稱的生成策略
			enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
            //這個是設置代理類的生成策略,也就是位元組碼生成策略,最終的位元組碼生成會由這個類來完成(調用它的generate方法)
			enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
			
            //這裡是設置代理中要使用的攔截器
			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
            //這裡是設置根據我們目標類不同的方法選擇不同的攔截器,根據不同的方法調用accept返回一個對應上面callbacks數組的下標,選擇不同的攔截器來處理
			enhancer.setCallbackFilter(new ProxyCallbackFilter(
					this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
			enhancer.setCallbackTypes(types);

			// Generate the proxy class and create a proxy instance.
            //最終在這裡會生成代理目標類,並創建對象
            //這裡需要注意的是:enhancer有個屬性useFactory默認是true,這時最終我們生成的代理類除了實現SpringProxy, Advised這兩個接口外也會實現org.springframework.cglib.proxy.Factory這個接口
            //在使用構造方法創建出來對象後會調用((Factory) proxyInstance).setCallbacks(callbacks)將我們上面創建的攔截器注入到對象上去
			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);
		}
	}

我們看看AopProxyUtils.completeProxiedInterfaces(this.advised)這個方法,這時AopProxyUtils的靜態方法

	public static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised) {
        //繼續進去看看
		return completeProxiedInterfaces(advised, false);
	}
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
    //這裡的advised就是前面創建的ProxyFactory對象,之前沒有添加過要代理的接口,specifiedInterfaces返回的是個空數組
		Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
		if (specifiedInterfaces.length == 0) {
			// No user-specified interfaces: check whether target class is an interface.
            //targetClass 是com.springboot.transaction.service.impl.UserServiceImpl
			Class<?> targetClass = advised.getTargetClass();
			if (targetClass != null) {
				if (targetClass.isInterface()) {
					advised.setInterfaces(targetClass);
				}
				else if (Proxy.isProxyClass(targetClass)) {
					advised.setInterfaces(targetClass.getInterfaces());
				}
				specifiedInterfaces = advised.getProxiedInterfaces();
			}
		}
    	//這句是判斷advised中的接口是否由SpringProxy的子類或子接口,當前advised不包含接口,所以這個是不包含的,注意這裡取反了。這個addSpringProxy 就是false
		boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
    	
    	//isOpaque()這個屬性是用來判斷是否應該阻止AOP代理轉換為 Advised,默認值為「false」,這意味着任何 AOP 代理都可以轉換為 Advised。當前這個也是false
    	//第2個條件是判斷當前advised是否有接口是Advised的子類或子接口,當前advised不包含接口,所以這個是不包含的,注意這裡取反了,這個addAdvised 就是true   
		boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
    
    	//這個decoratingProxy上層傳過來的,就是false
		boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
		int nonUserIfcCount = 0;
		if (addSpringProxy) {
			nonUserIfcCount++;
		}
		if (addAdvised) {
			nonUserIfcCount++;
		}
		if (addDecoratingProxy) {
			nonUserIfcCount++;
		}
    	
    	//下面就是根據上面判斷的值,設置目標代理類要實現的接口的數組大小,然後添加接口。
    	//我們這裡會添加兩個接口 SpringProxy.class,Advised.class
		Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
		System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
		int index = specifiedInterfaces.length;
		if (addSpringProxy) {
			proxiedInterfaces[index] = SpringProxy.class;
			index++;
		}
		if (addAdvised) {
			proxiedInterfaces[index] = Advised.class;
			index++;
		}
		if (addDecoratingProxy) {
			proxiedInterfaces[index] = DecoratingProxy.class;
		}
		return proxiedInterfaces;
	}

我們在這裡看看getCallbacks方法,這個方法在CglibAopProxy中

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

		// Choose an "aop" interceptor (used for AOP calls).
        //這裡會創建一個DynamicAdvisedInterceptor,最終的事務代理其實就是通過這個類來完成的
		Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

		// Choose a "straight to target" interceptor. (used for calls that are
		// unadvised but can return this). May be required to expose the proxy.
		Callback targetInterceptor;
		if (exposeProxy) {
			targetInterceptor = (isStatic ?
                    //這裡返回的是StaticUnadvisedExposedInterceptor,主要是對靜態的,不需要代理增強的方法用它來處理,內部實現也就是直接通過反射調用方法,沒有做其他處理           
					new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
					new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
		}
		else {
			targetInterceptor = (isStatic ?
					new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
					new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
		}

		// Choose a "direct to target" dispatcher (used for
		// unadvised calls to static targets that cannot return this).
		Callback targetDispatcher = (isStatic ?
                //這裡返回的是StaticDispatcher, 這個比較簡單,就是可以快速返回原始的類,我們這裡就是com.springboot.transaction.service.impl.UserServiceImpl                               
				new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());

        //這裡會將所有的攔截器都封裝都到callback數組中,最終生成的位元組碼中就會針對不同的方法分別使用不同的攔截器去處理。
		Callback[] mainCallbacks = new Callback[] {
				aopInterceptor,  // for normal advice
				targetInterceptor,  // invoke target without considering advice, if optimized
				new SerializableNoOp(),  // no override for methods mapped to this
				targetDispatcher, this.advisedDispatcher,
				new EqualsInterceptor(this.advised),
				new HashCodeInterceptor(this.advised)
		};

		Callback[] callbacks;

		// If the target is a static one and the advice chain is frozen,
		// then we can make some optimizations by sending the AOP calls
		// direct to the target using the fixed chain for that method.
		if (isStatic && isFrozen) {
			Method[] methods = rootClass.getMethods();
			Callback[] fixedCallbacks = new Callback[methods.length];
			this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);

			// TODO: small memory optimization here (can skip creation for methods with no advice)
			for (int x = 0; x < methods.length; x++) {
				Method method = methods[x];
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
				fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
						chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
				this.fixedInterceptorMap.put(method, x);
			}

			// Now copy both the callbacks from mainCallbacks
			// and fixedCallbacks into the callbacks array.
			callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
			System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
			System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
			this.fixedInterceptorOffset = mainCallbacks.length;
		}
		else {
			callbacks = mainCallbacks;
		}
		return callbacks;
	}

6. 最終生成的代理類class反編譯

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.springboot.transaction.service.impl;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor;
import org.springframework.aop.SpringProxy;
import org.springframework.aop.TargetClassAware;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Dispatcher;
import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;

public class UserServiceImpl$$EnhancerBySpringCGLIB$$fb4ce052 extends UserServiceImpl implements SpringProxy, Advised, Factory {
    private boolean CGLIB$BOUND;
    public static Object CGLIB$FACTORY_DATA;
    private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    private static final Callback[] CGLIB$STATIC_CALLBACKS;
    private MethodInterceptor CGLIB$CALLBACK_0;
    private MethodInterceptor CGLIB$CALLBACK_1;
    private NoOp CGLIB$CALLBACK_2;
    private Dispatcher CGLIB$CALLBACK_3;
    private Dispatcher CGLIB$CALLBACK_4;
    private MethodInterceptor CGLIB$CALLBACK_5;
    private MethodInterceptor CGLIB$CALLBACK_6;
    private static Object CGLIB$CALLBACK_FILTER;
    private static final Method CGLIB$findAll$0$Method;
    private static final MethodProxy CGLIB$findAll$0$Proxy;
    private static final Object[] CGLIB$emptyArgs;
    private static final Method CGLIB$equals$1$Method;
    private static final MethodProxy CGLIB$equals$1$Proxy;
    private static final Method CGLIB$toString$2$Method;
    private static final MethodProxy CGLIB$toString$2$Proxy;
    private static final Method CGLIB$hashCode$3$Method;
    private static final MethodProxy CGLIB$hashCode$3$Proxy;
    private static final Method CGLIB$clone$4$Method;
    private static final MethodProxy CGLIB$clone$4$Proxy;

    static void CGLIB$STATICHOOK9() {
        CGLIB$THREAD_CALLBACKS = new ThreadLocal();
        CGLIB$emptyArgs = new Object[0];
        Class var0 = Class.forName("com.springboot.transaction.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$fb4ce052");
        Class var1;
        Method[] var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
        CGLIB$equals$1$Method = var10000[0];
        CGLIB$equals$1$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$1");
        CGLIB$toString$2$Method = var10000[1];
        CGLIB$toString$2$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$2");
        CGLIB$hashCode$3$Method = var10000[2];
        CGLIB$hashCode$3$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$3");
        CGLIB$clone$4$Method = var10000[3];
        CGLIB$clone$4$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$4");
        CGLIB$findAll$0$Method = ReflectUtils.findMethods(new String[]{"findAll", "(Ljava/util/Map;)Ljava/util/List;"}, (var1 = Class.forName("com.springboot.transaction.service.impl.UserServiceImpl")).getDeclaredMethods())[0];
        CGLIB$findAll$0$Proxy = MethodProxy.create(var1, var0, "(Ljava/util/Map;)Ljava/util/List;", "findAll", "CGLIB$findAll$0");
    }

    final List CGLIB$findAll$0(Map var1) {
        return super.findAll(var1);
    }

    public final List findAll(Map var1) {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000 != null ? (List)var10000.intercept(this, CGLIB$findAll$0$Method, new Object[]{var1}, CGLIB$findAll$0$Proxy) : super.findAll(var1);
    }

    final boolean CGLIB$equals$1(Object var1) {
        return super.equals(var1);
    }

    public final boolean equals(Object var1) {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_5;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_5;
        }

        if (var10000 != null) {
            Object var2 = var10000.intercept(this, CGLIB$equals$1$Method, new Object[]{var1}, CGLIB$equals$1$Proxy);
            return var2 == null ? false : (Boolean)var2;
        } else {
            return super.equals(var1);
        }
    }

    final String CGLIB$toString$2() {
        return super.toString();
    }

    public final String toString() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000 != null ? (String)var10000.intercept(this, CGLIB$toString$2$Method, CGLIB$emptyArgs, CGLIB$toString$2$Proxy) : super.toString();
    }

    final int CGLIB$hashCode$3() {
        return super.hashCode();
    }

    public final int hashCode() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_6;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_6;
        }

        if (var10000 != null) {
            Object var1 = var10000.intercept(this, CGLIB$hashCode$3$Method, CGLIB$emptyArgs, CGLIB$hashCode$3$Proxy);
            return var1 == null ? 0 : ((Number)var1).intValue();
        } else {
            return super.hashCode();
        }
    }

    final Object CGLIB$clone$4() throws CloneNotSupportedException {
        return super.clone();
    }

    protected final Object clone() throws CloneNotSupportedException {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000 != null ? var10000.intercept(this, CGLIB$clone$4$Method, CGLIB$emptyArgs, CGLIB$clone$4$Proxy) : super.clone();
    }

    public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
        String var10000 = var0.toString();
        switch(var10000.hashCode()) {
        case -508378822:
            if (var10000.equals("clone()Ljava/lang/Object;")) {
                return CGLIB$clone$4$Proxy;
            }
            break;
        case 211025071:
            if (var10000.equals("findAll(Ljava/util/Map;)Ljava/util/List;")) {
                return CGLIB$findAll$0$Proxy;
            }
            break;
        case 1826985398:
            if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
                return CGLIB$equals$1$Proxy;
            }
            break;
        case 1913648695:
            if (var10000.equals("toString()Ljava/lang/String;")) {
                return CGLIB$toString$2$Proxy;
            }
            break;
        case 1984935277:
            if (var10000.equals("hashCode()I")) {
                return CGLIB$hashCode$3$Proxy;
            }
        }

        return null;
    }

    public final int indexOf(Advisor var1) {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).indexOf(var1);
    }

    public final int indexOf(Advice var1) {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).indexOf(var1);
    }

    public final boolean isFrozen() {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).isFrozen();
    }

    public final boolean isInterfaceProxied(Class var1) {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).isInterfaceProxied(var1);
    }

    public final TargetSource getTargetSource() {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).getTargetSource();
    }

    public final int getAdvisorCount() {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).getAdvisorCount();
    }

    public final boolean isProxyTargetClass() {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).isProxyTargetClass();
    }

    public final void setTargetSource(TargetSource var1) {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        ((Advised)var10000.loadObject()).setTargetSource(var1);
    }

    public final void setExposeProxy(boolean var1) {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        ((Advised)var10000.loadObject()).setExposeProxy(var1);
    }

    public final Advisor[] getAdvisors() {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).getAdvisors();
    }

    public final void addAdvisor(Advisor var1) throws AopConfigException {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        ((Advised)var10000.loadObject()).addAdvisor(var1);
    }

    public final void addAdvisor(int var1, Advisor var2) throws AopConfigException {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        ((Advised)var10000.loadObject()).addAdvisor(var1, var2);
    }

    public final boolean replaceAdvisor(Advisor var1, Advisor var2) throws AopConfigException {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).replaceAdvisor(var1, var2);
    }

    public final boolean isExposeProxy() {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).isExposeProxy();
    }

    public final boolean isPreFiltered() {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).isPreFiltered();
    }

    public final void setPreFiltered(boolean var1) {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        ((Advised)var10000.loadObject()).setPreFiltered(var1);
    }

    public final boolean removeAdvice(Advice var1) {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).removeAdvice(var1);
    }

    public final boolean removeAdvisor(Advisor var1) {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).removeAdvisor(var1);
    }

    public final void removeAdvisor(int var1) throws AopConfigException {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        ((Advised)var10000.loadObject()).removeAdvisor(var1);
    }

    public final void addAdvice(Advice var1) throws AopConfigException {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        ((Advised)var10000.loadObject()).addAdvice(var1);
    }

    public final void addAdvice(int var1, Advice var2) throws AopConfigException {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        ((Advised)var10000.loadObject()).addAdvice(var1, var2);
    }

    public final Class[] getProxiedInterfaces() {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).getProxiedInterfaces();
    }

    public final String toProxyConfigString() {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((Advised)var10000.loadObject()).toProxyConfigString();
    }

    public final Class getTargetClass() {
        Dispatcher var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return ((TargetClassAware)var10000.loadObject()).getTargetClass();
    }

    public UserServiceImpl$$EnhancerBySpringCGLIB$$fb4ce052() {
        CGLIB$BIND_CALLBACKS(this);
    }

    public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
        CGLIB$THREAD_CALLBACKS.set(var0);
    }

    public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
        CGLIB$STATIC_CALLBACKS = var0;
    }

    private static final void CGLIB$BIND_CALLBACKS(Object var0) {
        UserServiceImpl$$EnhancerBySpringCGLIB$$fb4ce052 var1 = (UserServiceImpl$$EnhancerBySpringCGLIB$$fb4ce052)var0;
        if (!var1.CGLIB$BOUND) {
            var1.CGLIB$BOUND = true;
            Object var10000 = CGLIB$THREAD_CALLBACKS.get();
            if (var10000 == null) {
                var10000 = CGLIB$STATIC_CALLBACKS;
                if (var10000 == null) {
                    return;
                }
            }

            Callback[] var10001 = (Callback[])var10000;
            var1.CGLIB$CALLBACK_6 = (MethodInterceptor)((Callback[])var10000)[6];
            var1.CGLIB$CALLBACK_5 = (MethodInterceptor)var10001[5];
            var1.CGLIB$CALLBACK_4 = (Dispatcher)var10001[4];
            var1.CGLIB$CALLBACK_3 = (Dispatcher)var10001[3];
            var1.CGLIB$CALLBACK_2 = (NoOp)var10001[2];
            var1.CGLIB$CALLBACK_1 = (MethodInterceptor)var10001[1];
            var1.CGLIB$CALLBACK_0 = (MethodInterceptor)var10001[0];
        }

    }

    public Object newInstance(Callback[] var1) {
        CGLIB$SET_THREAD_CALLBACKS(var1);
        UserServiceImpl$$EnhancerBySpringCGLIB$$fb4ce052 var10000 = new UserServiceImpl$$EnhancerBySpringCGLIB$$fb4ce052();
        CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
        return var10000;
    }

    public Object newInstance(Callback var1) {
        throw new IllegalStateException("More than one callback object required");
    }

    public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
        CGLIB$SET_THREAD_CALLBACKS(var3);
        UserServiceImpl$$EnhancerBySpringCGLIB$$fb4ce052 var10000 = new UserServiceImpl$$EnhancerBySpringCGLIB$$fb4ce052;
        switch(var1.length) {
        case 0:
            var10000.<init>();
            CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
            return var10000;
        default:
            throw new IllegalArgumentException("Constructor not found");
        }
    }

    public Callback getCallback(int var1) {
        CGLIB$BIND_CALLBACKS(this);
        Object var10000;
        switch(var1) {
        case 0:
            var10000 = this.CGLIB$CALLBACK_0;
            break;
        case 1:
            var10000 = this.CGLIB$CALLBACK_1;
            break;
        case 2:
            var10000 = this.CGLIB$CALLBACK_2;
            break;
        case 3:
            var10000 = this.CGLIB$CALLBACK_3;
            break;
        case 4:
            var10000 = this.CGLIB$CALLBACK_4;
            break;
        case 5:
            var10000 = this.CGLIB$CALLBACK_5;
            break;
        case 6:
            var10000 = this.CGLIB$CALLBACK_6;
            break;
        default:
            var10000 = null;
        }

        return (Callback)var10000;
    }

    public void setCallback(int var1, Callback var2) {
        switch(var1) {
        case 0:
            this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2;
            break;
        case 1:
            this.CGLIB$CALLBACK_1 = (MethodInterceptor)var2;
            break;
        case 2:
            this.CGLIB$CALLBACK_2 = (NoOp)var2;
            break;
        case 3:
            this.CGLIB$CALLBACK_3 = (Dispatcher)var2;
            break;
        case 4:
            this.CGLIB$CALLBACK_4 = (Dispatcher)var2;
            break;
        case 5:
            this.CGLIB$CALLBACK_5 = (MethodInterceptor)var2;
            break;
        case 6:
            this.CGLIB$CALLBACK_6 = (MethodInterceptor)var2;
        }

    }

    public Callback[] getCallbacks() {
        CGLIB$BIND_CALLBACKS(this);
        return new Callback[]{this.CGLIB$CALLBACK_0, this.CGLIB$CALLBACK_1, this.CGLIB$CALLBACK_2, this.CGLIB$CALLBACK_3, this.CGLIB$CALLBACK_4, this.CGLIB$CALLBACK_5, this.CGLIB$CALLBACK_6};
    }

    public void setCallbacks(Callback[] var1) {
        this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
        this.CGLIB$CALLBACK_1 = (MethodInterceptor)var1[1];
        this.CGLIB$CALLBACK_2 = (NoOp)var1[2];
        this.CGLIB$CALLBACK_3 = (Dispatcher)var1[3];
        this.CGLIB$CALLBACK_4 = (Dispatcher)var1[4];
        this.CGLIB$CALLBACK_5 = (MethodInterceptor)var1[5];
        this.CGLIB$CALLBACK_6 = (MethodInterceptor)var1[6];
    }

    static {
        CGLIB$STATICHOOK9();
    }
}

Tags: