SpringAOP源码解析(二)


在上篇文章中我们简单介绍了aop导入过程,其中 @EnableAspectJAutoProxy注解最主要的功能就是想Spring注册了 AnnotationAwareAspectJAutoProxyCreator,下面我们先看一眼此类的继承图:

image-20211026094741544

观察类图可知,AnnotationAwareAspectJAutoProxyCreator这个类间接实现了BeanPostProcessor接口。我们知道在Spring实例化Bean的前后会分别调用实现BeanPostProcessor 接口类的postProcessBeforeInstantiationpostProcessAfterInitialization方法。AOP也是基于这两个方法实现的。

postProcessBeforeInstantiation

	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
     	...
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}
		...
	}
shouldSkip
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
	...
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
	...
}
  • findCandidateAdvisors 我们知道一般在使用aop功能时会使用@Aspect注解,被此注解标注的类中会有@Pointcut@Before@After@AfterReturning@AfterThrowing@Around标注的方法,后五个被称为Advice。Pointcut+Advice被我们称为Advisor。此方法就是寻找所有的Advisor
findCandidateAdvisors
protected List<Advisor> findCandidateAdvisors() {
   // Add all the Spring advisors found according to superclass rules.
   //找到所有的Advisor
   List<Advisor> advisors = super.findCandidateAdvisors();
   // Build Advisors for all AspectJ aspects in the bean factory.
   //主要看这里,创建候选的切面  对@Aspect注解的类进行处理
   if (this.aspectJAdvisorsBuilder != null) {
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}
  • buildAspectJAdvisors找到配对的PointcutAdvice构建Advisor
buildAspectJAdvisors
public List<Advisor> buildAspectJAdvisors() {
   List<String> aspectNames = this.aspectBeanNames;

   if (aspectNames == null) {
      synchronized (this) {
         aspectNames = this.aspectBeanNames;
         if (aspectNames == null) {
            List<Advisor> advisors = new ArrayList<>();
            aspectNames = new ArrayList<>();
            //获取spring容器中的所有bean的名称BeanName
            String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                  this.beanFactory, Object.class, true, false);
            for (String beanName : beanNames) {
               if (!isEligibleBean(beanName)) {
                  continue;
               }
               // We must be careful not to instantiate beans eagerly as in this case they
               // would be cached by the Spring container but would not have been weaved.
               Class<?> beanType = this.beanFactory.getType(beanName);
               if (beanType == null) {
                  continue;
               }
               //判断类上是否有@Aspect注解
               if (this.advisorFactory.isAspect(beanType)) {
                  aspectNames.add(beanName);
                  AspectMetadata amd = new AspectMetadata(beanType, beanName);
                  if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {

                     //创建获取有@Aspect注解类的实例工厂,负责获取有@Aspect注解类的实例
                     MetadataAwareAspectInstanceFactory factory =
                           new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);

                     //创建切面advisor对象
                     List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                     if (this.beanFactory.isSingleton(beanName)) {
                        this.advisorsCache.put(beanName, classAdvisors);
                     }
                     else {
                        this.aspectFactoryCache.put(beanName, factory);
                     }
                     advisors.addAll(classAdvisors);
                  }
                  else {
                     // Per target or per this.
                     if (this.beanFactory.isSingleton(beanName)) {
                        throw new IllegalArgumentException("Bean with name '" + beanName +
                              "' is a singleton, but aspect instantiation model is not singleton");
                     }
                     MetadataAwareAspectInstanceFactory factory =
                           new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                     this.aspectFactoryCache.put(beanName, factory);
                     advisors.addAll(this.advisorFactory.getAdvisors(factory));
                  }
               }
            }
            this.aspectBeanNames = aspectNames;
            return advisors;
         }
      }
   }

   if (aspectNames.isEmpty()) {
      return Collections.emptyList();
   }
   List<Advisor> advisors = new ArrayList<>();
   for (String aspectName : aspectNames) {
      List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
      if (cachedAdvisors != null) {
         advisors.addAll(cachedAdvisors);
      }
      else {
         MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
         advisors.addAll(this.advisorFactory.getAdvisors(factory));
      }
   }
   return advisors;
}
  • getAdvisors
getAdvisors
	public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
		...
		List<Advisor> advisors = new ArrayList<>();
		//这里循环没有@Pointcut注解的方法
		for (Method method : getAdvisorMethods(aspectClass)) {
			//获取Advisor
			Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
			if (advisor != null) {
				advisors.add(advisor);
			}
		}
		...
	}
  • getAdvisorMethods(aspectClass)获得类中所有没有@Pointcut注解的方法。
  • getAdvisor生成增强实例
getAdvisor
	public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
			int declarationOrderInAspect, String aspectName) {

		validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());

		//获取pointCut对象,最重要的是从注解中获取表达式
		AspectJExpressionPointcut expressionPointcut = getPointcut(
				candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
		if (expressionPointcut == null) {
			return null;
		}

		//创建Advisor切面类,这才是真正的切面类,一个切面类里面肯定要有1、pointCut 2、advice
		//这里pointCut是expressionPointcut, advice 增强方法是 candidateAdviceMethod
		//根据方法、切点、AOP实例工厂、类名、序号生成切面实例
		return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
				this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
	}
  • getPointcut
  • new InstantiationModelAwarePointcutAdvisorImpl()
getPointcut
	private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
		//从候选的增强方法里面 candidateAdviceMethod  找有有注解
		//Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
		//并把注解信息封装成AspectJAnnotation对象
		//查询方法上的切面注解,根据注解生成相应类型的AspectJAnnotation,在调用AspectJAnnotation的构造函数的同时
		//根据注解value或pointcut属性得到切点表达式,有argNames则设置参数名称
		AspectJAnnotation<?> aspectJAnnotation =
				AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
		if (aspectJAnnotation == null) {
			return null;
		}

		//创建一个PointCut类,并且把前面从注解里面解析的表达式设置进去
		AspectJExpressionPointcut ajexp =
				new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
		ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
		if (this.beanFactory != null) {
			ajexp.setBeanFactory(this.beanFactory);
		}
		return ajexp;
	}
  • findAspectJAnnotationOnMethod
  • new AspectJExpressionPointcut()
findAspectJAnnotationOnMethod
	protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
		//Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
		for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
			//找到Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
			//注解的方法,并且把注解里面的信息封装成AspectJAnnotation对象
			AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
			if (foundAnnotation != null) {
				return foundAnnotation;
			}
		}
		return null;
	}
  • findAnnotation
findAnnotation
	private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
		A result = AnnotationUtils.findAnnotation(method, toLookFor);
		if (result != null) {
			//把注解里面的信息解析出来,然后包装成AspectJAnnotation对象
            //获取注解上的参数(argNames)
			return new AspectJAnnotation<>(result);
		}
		else {
			return null;
		}
	}

至此在getAdvisor 方法中调用的getPointcut方法逻辑分析完毕,下面分析getAdvisor 方法中调用new InstantiationModelAwarePointcutAdvisorImpl()的逻辑。

new InstantiationModelAwarePointcutAdvisorImpl()
	public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
			Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
			MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

			...
			//创建advice对象
			this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
			...
	}
  • instantiateAdvice
instantiateAdvice
	private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
		//创建Advice对象
		Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
				this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
		return (advice != null ? advice : EMPTY_ADVICE);
	}
  • getAdvice
getAdvice
	public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
			MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

		//获取有@Aspect注解的类
		Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
		validate(candidateAspectClass);

		//找到candidateAdviceMethod方法上面的注解,并且包装成AspectJAnnotation对象,这个对象中就有注解类型
		AspectJAnnotation<?> aspectJAnnotation =
				AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
        ...

		//根据不同的注解类型创建不同的advice类实例
		switch (aspectJAnnotation.getAnnotationType()) {
			case AtPointcut:
				if (logger.isDebugEnabled()) {
					logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
				}
				return null;
			case AtAround:
				//实现了MethodInterceptor接口
				springAdvice = new AspectJAroundAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			case AtBefore:
				//实现了MethodBeforeAdvice接口,没有实现MethodInterceptor接口
				springAdvice = new AspectJMethodBeforeAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			case AtAfter:
				//实现了MethodInterceptor接口
				springAdvice = new AspectJAfterAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			case AtAfterReturning:
				//实现了AfterReturningAdvice接口,没有实现MethodInterceptor接口
				springAdvice = new AspectJAfterReturningAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
				if (StringUtils.hasText(afterReturningAnnotation.returning())) {
					springAdvice.setReturningName(afterReturningAnnotation.returning());
				}
				break;
			case AtAfterThrowing:
				//实现了MethodInterceptor接口
				springAdvice = new AspectJAfterThrowingAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
				if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
					springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
				}
				break;
			default:
				throw new UnsupportedOperationException(
						"Unsupported advice type on method: " + candidateAdviceMethod);
		}

		// Now to configure the advice...
		//设置通知方法所属的类
		springAdvice.setAspectName(aspectName);
		springAdvice.setDeclarationOrder(declarationOrder);
		//获取注解中的argNames属性参数名称
		String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
		if (argNames != null) {
			springAdvice.setArgumentNamesFromStringArray(argNames);
		}
		//计算argNames和类型的对应关系
		springAdvice.calculateArgumentBindings();

		return springAdvice;
	}
小结

​ 至此,在AnnotationAwareAspectJAutoProxyCreatorpostProcessBeforeInstantiation方法分析完毕,即在bean实列化前aop准备工作分析完毕。下面分析bean实列化后aop所做的工作,即分析AnnotationAwareAspectJAutoProxyCreatorpostProcessAfterInitialization方法。

postProcessAfterInitialization

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator中的postProcessAfterInitialization方法调用栈如下:

image-20211026103012145

此方法核心代码如下:

	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		...
        return wrapIfNecessary(bean, beanName, cacheKey);
		...
	}
wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	...
   //判断当前bean是否有切面
   //创建当前bean的代理,如果这个bean有advice的话,重点看,重要程度5
   // Create proxy if we have advice.
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    ...
    //如果有切面,则生成该bean的代理
    //把被代理对象bean实例封装到SingletonTargetSource对象中
    Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

	...
}
  • getAdvicesAndAdvisorsForBean找到所有的合格的切面

  • createProxy如果有合格的切面,则创建代理

getAdvicesAndAdvisorsForBean
	protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
	...
		//找到合格的切面,重点看
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
	...
	}
  • findEligibleAdvisors
findEligibleAdvisors
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   //找到候选的切面,其实就是一个寻找有@Aspectj注解的过程,把工程中所有有这个注解的类封装成Advisor返回
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   //判断候选的切面是否作用在当前beanClass上面,就是一个匹配过程。。现在就是一个匹配
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
   //针对@Aspect注解切面添加了一个默认的切面 DefaultPointcutAdvisor
   extendAdvisors(eligibleAdvisors);
   if (!eligibleAdvisors.isEmpty()) {
      //对有@Order@Priority进行排序
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}
  • findCandidateAdvisors 找到所有的Advisor。我们知道一般在使用aop功能时会使用@Aspect注解,被此注解标注的类中会有@Pointcut@Before@After@AfterReturning@AfterThrowing@Around标注的方法,后五个被称为Advice。Pointcut+Advice被我们称为Advisor。此方法就是寻找所有的Advisor

  • findAdvisorsThatCanApply

  • extendAdvisors 针对@Aspect注解切面添加了一个默认的切面 DefaultPointcutAdvisor

findCandidateAdvisors
	protected List<Advisor> findCandidateAdvisors() {
		// Add all the Spring advisors found according to superclass rules.
		//找到所有的Advisor
		List<Advisor> advisors = super.findCandidateAdvisors();
		// Build Advisors for all AspectJ aspects in the bean factory.
		//主要看这里,创建候选的切面  对@Aspect注解的类进行处理
		if (this.aspectJAdvisorsBuilder != null) {
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		return advisors;
	}

buildAspectJAdvisors

buildAspectJAdvisors
	public List<Advisor> buildAspectJAdvisors() {
		List<String> aspectNames = this.aspectBeanNames;

		if (aspectNames == null) {
			...
		}

		if (aspectNames.isEmpty()) {
			return Collections.emptyList();
		}
		List<Advisor> advisors = new ArrayList<>();
		for (String aspectName : aspectNames) {
			List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
			if (cachedAdvisors != null) {
				advisors.addAll(cachedAdvisors);
			}
			else {
				MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
				advisors.addAll(this.advisorFactory.getAdvisors(factory));
			}
		}
		return advisors;
	}

  • 由于在postProcessBeforeInstantiation中已经找到了所有的Advisor,顾此处的advisors必定是从缓存里拿的。同理,此处aspectNames不为空,所以第一个if不会执行。
findAdvisorsThatCanApply
	protected List<Advisor> findAdvisorsThatCanApply(
			List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

		
		//将beanName放入ThreadLocal中
		ProxyCreationContext.setCurrentProxiedBeanName(beanName);
		try {
			//看看当前类是否在这些切面的pointCut中..掉类和方法的match过程
			return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
		}
		finally {
			//将ThreadLocal置空
			ProxyCreationContext.setCurrentProxiedBeanName(null);
		}
	}
  • findAdvisorsThatCanApply
findAdvisorsThatCanApply
	public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
		...
		//调用pointCut中的ClassFilter 和methodMatcher的match方法的过程
		for (Advisor candidate : candidateAdvisors) {
			...
			//candidate切面
			if (canApply(candidate, clazz, hasIntroductions)) {
				eligibleAdvisors.add(candidate);
			}
		}
		...
	}
  • canApply
canApply
	public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
		...
		else if (advisor instanceof PointcutAdvisor) {
			PointcutAdvisor pca = (PointcutAdvisor) advisor;
			return canApply(pca.getPointcut(), targetClass, hasIntroductions);
    }
		...
	}
  • canApply
canApply
	public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
		Assert.notNull(pc, "Pointcut must not be null");
		//调用ClassFilter的matches方法,判断类是否匹配
        //这里会将形如@Around("pc1()")配置中的pc1找到pc1方法从而找到真正的pointCut表达式
		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;
		}

		...

		//判断类中方法是否匹配,,有些可能是方法上面有注解的拦截,所以需要判断方法是否匹配
		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;
	}
  • targetClass中有方法匹配切面则返回true。

  • 至此,我们完成了对拦截目标bean的Advisor的收集,即完成了对wrapIfNecessarygetAdvicesAndAdvisorsForBean方法的分析,下面我们将进行对wrapIfNecessarycreateProxy方法的分析

extendAdvisors
	protected void extendAdvisors(List<Advisor> candidateAdvisors) {
		AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
	}
  • makeAdvisorChainAspectJCapableIfNecessary
makeAdvisorChainAspectJCapableIfNecessary
	public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
		...
        advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
		...
	}
  • 在所有advisor前添加一个全局advisor
createProxy
	protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {

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

		ProxyFactory proxyFactory = new ProxyFactory();
		//把AnnotationAwareAspectJAutoProxyCreator中的某些属性copy到proxyFactory中
		proxyFactory.copyFrom(this);

		//判断是否使用Cglib动态代理
		if (!proxyFactory.isProxyTargetClass()) {
			//如果配置开启使用则直接设置开启
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				//如果没有配置开启则判断bean是否有合适的接口使用JDK的动态代理(JDK动态代理必须是带有接口的类,如果类没有实现任何接口则只能使用Cglib动态代理)
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
		//组装advisor
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		//把advisor加入到proxyFactory
		//添加所有增强
		proxyFactory.addAdvisors(advisors);
		//把targetSource对象加入到proxyFactory
		//设置要代理的类
		proxyFactory.setTargetSource(targetSource);
		//Spring的一个扩展点,默认实现为空。留给我们在需要对代理进行特殊操作的时候实现
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
		//获取代理对象
		//使用代理工厂获取代理对象
		return proxyFactory.getProxy(getProxyClassLoader());
	}
  • getProxy
getProxy
	public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}
  • createAopProxy
createAopProxy
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		return getAopProxyFactory().createAopProxy(this);
	}
  • createAopProxy
createAopProxy
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			Class<?> targetClass = config.getTargetClass();
			if (targetClass == null) {
				throw new AopConfigException("TargetSource cannot determine target class: " +
						"Either an interface or a target is required for proxy creation.");
			}
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}
  • 根据条件选择Jdk代理或者Cglib代理
小结

自此对目标bean的代理创建完毕。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值