写点什么

这才是 Springboot 事务创建流程的正确打开方式(附源码分析!)

  • 2021 年 11 月 26 日
  • 本文字数:25891 字

    阅读完需:约 85 分钟

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@Nullablepublic 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 方法去看看代理类的生成过程

//这个方法在AbstractAutoProxyCreatorprotected 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(); }}
复制代码


用户头像

还未添加个人签名 2021.10.14 加入

还未添加个人简介

评论

发布
暂无评论
这才是Springboot事务创建流程的正确打开方式(附源码分析!)