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