当前位置:   article > 正文

SpringBoot Aop原理介绍

springboot aop原理

SpringBoot Aop 简介

  • Aspect(切面):通常是一个类,里面可以定义切入点和通知
  • JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用
  • Advice(通知):AOP在特定的切入点上执行的增强处理, before,after,afterReturning,afterThrowing,around
  • Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式
  • AOP代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于类

@EnableAspectJAutoProxy 注解

首先看下该注解定义发现该注解含有两个参数化分别为proxyTargetClassexposeProxy

  • proxyTargetClass=true 表示使用cglib作为动态代理,false为jdk动态代理
  • exposeProxy=true 表示用代理对象暴露保证在嵌套调用时aop生效

接下来看@Import注解中AspectJAutoProxyRegistrar类,该类作为aop beanDefination加载入口类

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
	boolean proxyTargetClass() default false;
	boolean exposeProxy() default false;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

接续分析AspectJAutoProxyRegistrar中主要完成功能

  • 注册AnnotationAwareAspectJAutoProxyCreator到spring的beanDefination中
  • 设置proxyTargetClass
  • 设置exposeProxy
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
	    // 创建AnnotationAwareAspectJAutoProxyCreator,该类实现了BeanPostProcessor接口,此接口为spring bean的后置处理器
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
		AnnotationAttributes enableAspectJAutoProxy =AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

SpringBoot Aop在初始化bean时通过后置处理器BeanPostProcessor来判断对象是否满足aop的条件并进行动态代理接下来重点分AnnotationAwareAspectJAutoProxyCreator

@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
	return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}

@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
 // 将AnnotationAwareAspectJAutoProxyCreator生成beanDefination 并注册到spring中
   return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
		BeanDefinition apcDefinition=registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
		if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
			int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
			int requiredPriority = findPriorityForClass(cls);
			if (currentPriority < requiredPriority) {
				apcDefinition.setBeanClassName(cls.getName());
			}
		}
			return null;
	}

	RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
	beanDefinition.setSource(source);
	beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
	beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
	return beanDefinition;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

接下来看下AnnotationAwareAspectJAutoProxyCreator类图其父类

在这里插入图片描述
其父类AbstractAutoProxyCreator实现了BeanPostProcessor接口,该接口是bean初始化后置处理器,BeanPostProcessor实际调用是在AbstractAutowireCapableBeanFactory中initializeBean方法

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	 }
	else {
	//由于AbstractAutoProxyCreator实现了BeanFactoryAware接口所以此处会设置beanFactory
	  invokeAwareMethods(beanName, bean);
	}

	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
	//初始化前处理
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}
	try {
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
	  throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
	}
	if (mbd == null || !mbd.isSynthetic()) {
	   //初始化后处理
	   wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

接下来重点分析AbstractAutoProxyCreator中postProcessBeforeInstantiation方法
通过isInfrastructureClass通过名字可以看出这是aop的基础类包括(Advice.class,Pointcut.class,Advisor.class,@Aspect),shouldSkip找到不可代理对象并存储,判断用户是否设置自定义创建代理方法

@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
	Object cacheKey = getCacheKey(beanClass, beanName);
    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
       if (this.advisedBeans.containsKey(cacheKey)) {
          return null;
	   }
	   //将不可代理bean放入advisedBeans 
	   if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
		  this.advisedBeans.put(cacheKey, Boolean.FALSE);
		  return null;
	   }
	 }

	// Create proxy here if we have a custom TargetSource.
	// Suppresses unnecessary default instantiation of the target bean:
	// The TargetSource will handle target instances in a custom fashion.
	TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
	if (targetSource != null) {
	   if (StringUtils.hasLength(beanName)) {
		  this.targetSourcedBeans.add(beanName);
	   }
	   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
	   Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
	   this.proxyTypes.put(cacheKey, proxy.getClass());
	   return proxy;
	}

	return null;
}

/**
 * Create a proxy with the configured interceptors if the bean is
 * identified as one to proxy by the subclass.
 * @see #getAdvicesAndAdvisorsForBean
 */
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (this.earlyProxyReferences.remove(cacheKey) != bean) {
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

接下来分析wrapIfNecessary方法该方法主要通过getAdvicesAndAdvisorsForBean获取Advice和Advisor并生成代理,这里说下Advice是aop联盟下的注解,Advisor是spring aop的注解

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.
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

继续进入到getAdvicesAndAdvisorsForBean方法,该方法调用链是findEligibleAdvisors->findCandidateAdvisors,findCandidateAdvisors是一个模版方法子类AnnotationAwareAspectJAutoProxyCreator中实现,通过类名也可看出这个是创建Aspectj的,该类中的aspectJAdvisorsBuilder正是上文中所说BeanFactoryAware进行设置的

List advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}

@Override
@Nullable
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) {
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	extendAdvisors(eligibleAdvisors);
	if (!eligibleAdvisors.isEmpty()) {
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	return eligibleAdvisors;
}

protected List<Advisor> findCandidateAdvisors() {
    Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
	return this.advisorRetrievalHelper.findAdvisorBeans();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

super.findCandidateAdvisors();为AbstractAdvisorAutoProxyCreator中方法,该方法比较简单,通过spring bean factory中找到当前类或者父类为Advisor的bean

public List<Advisor> findAdvisorBeans() {
   	// Determine list of advisor bean names, if not cached already.
   	String[] advisorNames = this.cachedAdvisorBeanNames;
   	if (advisorNames == null) {
   	//获取Advisor类的bean name
   		advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
   				this.beanFactory, Advisor.class, true, false);
   		this.cachedAdvisorBeanNames = advisorNames;
   	}
   	if (advisorNames.length == 0) {
   		return new ArrayList<>();
   	}

   	List<Advisor> advisors = new ArrayList<>();
   	for (String name : advisorNames) {
   		if (isEligibleBean(name)) {
   			if (this.beanFactory.isCurrentlyInCreation(name)) {
   				if (logger.isTraceEnabled()) {
   					logger.trace("Skipping currently created advisor '" + name + "'");
   				}
   			}
   			else {
   				try {
   				//将对应的bean放入到advisor中
   					advisors.add(this.beanFactory.getBean(name, Advisor.class));
   				}
   				catch (BeanCreationException ex) {
   					Throwable rootCause = ex.getMostSpecificCause();
   					if (rootCause instanceof BeanCurrentlyInCreationException) {
   						BeanCreationException bce = (BeanCreationException) rootCause;
   						String bceBeanName = bce.getBeanName();
   						if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
   							if (logger.isTraceEnabled()) {
   								logger.trace("Skipping advisor '" + name +
   										"' with dependency on currently created bean: " + ex.getMessage());
   							}
   							// Ignore: indicates a reference back to the bean we're trying to advise.
   							// We want to find advisors other than the currently created bean itself.
   							continue;
   						}
   					}
   					throw ex;
   				}
   			}
   		}
   	}
   	return advisors;
   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

通过上午解析了Advisor的bean 接下来解析AspectJ的bean,具体的工作在注释中

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 中所有beanName
   				String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
   						this.beanFactory, Object.class, true, false);
   				//循环判断每一个beanName
   				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;
   					}
   					//通过当前类判断是否有@AspecJ注解
   					if (this.advisorFactory.isAspect(beanType)) {
   						aspectNames.add(beanName);
   						//通过反射获取当前类的meta信息
   						AspectMetadata amd = new AspectMetadata(beanType, beanName);
   						if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
   							MetadataAwareAspectInstanceFactory factory =
   									new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
   							//生成spring aop advisor,该方法中会解析Advice和Pointcut注解
   							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;
   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

继续分析getAdvisors中方法逻辑

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
   	Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
   	String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
   	validate(aspectClass);

   	// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
   	// so that it will only instantiate once.
   	MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
   			new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

   	List<Advisor> advisors = new ArrayList<>();
   	// 遍历所有没有 @Pointcut注解的方法
   	for (Method method : getAdvisorMethods(aspectClass)) {
   		Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
   		if (advisor != null) {
   			advisors.add(advisor);
   		}
   	}

   	// If it's a per target aspect, emit the dummy instantiating aspect.
   	if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
   		Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
   		advisors.add(0, instantiationAdvisor);
   	}

   	// Find introduction fields.
   	for (Field field : aspectClass.getDeclaredFields()) {
   		Advisor advisor = getDeclareParentsAdvisor(field);
   		if (advisor != null) {
   			advisors.add(advisor);
   		}
   	}

   	return advisors;
   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

继续分析getAdvisor方法此方法中真正开始解析aop @Before中注解

Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);

public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
			int declarationOrderInAspect, String aspectName) {

		validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
		//获取通知相关注解
		AspectJExpressionPointcut expressionPointcut = getPointcut(
				candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
		if (expressionPointcut == null) {
			return null;
		}
		//最终生成Advisor类
		return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
				this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
	}

	@Nullable
	private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
		AspectJAnnotation<?> aspectJAnnotation =AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
		if (aspectJAnnotation == null) {
			return null;
		}

		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;
	}
// 判断当前方法注解是否含有 Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
	for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
		AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
		if (foundAnnotation != null) {
			return foundAnnotation;
		}
	}
	return null;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

InstantiationModelAwarePointcutAdvisorImpl构造方法中会调用getAdvice 生成通知

public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
			MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

		Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
		validate(candidateAspectClass);

		AspectJAnnotation<?> aspectJAnnotation =
				AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
		if (aspectJAnnotation == null) {
			return null;
		}

		// If we get here, we know we have an AspectJ method.
		// Check that it's an AspectJ-annotated class
		if (!isAspect(candidateAspectClass)) {
			throw new AopConfigException("Advice must be declared inside an aspect type: " +
					"Offending method '" + candidateAdviceMethod + "' in class [" +
					candidateAspectClass.getName() + "]");
		}

		if (logger.isDebugEnabled()) {
			logger.debug("Found AspectJ method: " + candidateAdviceMethod);
		}

		AbstractAspectJAdvice springAdvice;

		switch (aspectJAnnotation.getAnnotationType()) {
			case AtPointcut:
				if (logger.isDebugEnabled()) {
					logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
				}
				return null;
			case AtAround:
				springAdvice = new AspectJAroundAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			case AtBefore:
				springAdvice = new AspectJMethodBeforeAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			case AtAfter:
				springAdvice = new AspectJAfterAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			case AtAfterReturning:
				springAdvice = new AspectJAfterReturningAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
				if (StringUtils.hasText(afterReturningAnnotation.returning())) {
					springAdvice.setReturningName(afterReturningAnnotation.returning());
				}
				break;
			case AtAfterThrowing:
				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);
		String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
		if (argNames != null) {
			springAdvice.setArgumentNamesFromStringArray(argNames);
		}
		springAdvice.calculateArgumentBindings();

		return springAdvice;
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

至此切面构造完成最后是代理类创建部分

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

在创建代理时根据targetClass 属性来判断是CGlib还是JDK动态代理

@Override
	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);
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/140537
推荐阅读
相关标签
  

闽ICP备14008679号