Spring5 源码阅读笔记(3.1)getAdvicesAndAdvisorsForBean 为Bean拿到增强与切面

主要流程

1 找到所有的候选切面 findCandidateAdvisors
	1.1 获取所有的 BeanDefinition 的名称,进而获取所有的 Class 对象
	1.2 将 Class 里有 @Aspect 注解信息的收集起来
	1.3 根据有 @Aspect 注解信息的类获取切面 getAdvisors
		1.3.1 找到所有没有 @PointCut 注解的方法 getAdvisorMethods
			  1.3.1.1 每一个找到的方法都可以创建一个切面 getAdvisor
			  	      1.3.1.1.1 找到这个 Advisor 里的切点 getPointCut
			  	      		    1.3.1.1.1.1 获取方法上面的注解,封装成 AspectJAnnotation 对象 findAspectJAnnotationOnMethod 
			  	      		    1.3.1.1.1.2 创建 AspectJExpressionPointcut 对象,把 AspectJAnnotation  中的表达式设置进去
			  	      1.3.1.1.2 创建 InstantiationModelAwarePointCutAdvisorImpl 对象
			  	      			1.3.1.1.2.1 实例化增强 instantiateAdvice 拿到增强 getAdvice
			  	      						1.3.1.1.2.1.1 找到方法上的注解,封装成 AspectJAnnotation 对象
			  	      						1.3.1.1.2.1.2 根据注解类型的不同,创建不同的 Advice对象
2 利用 Advisor 里的 PointCut 和当前 bean 进行模糊匹配 findAdvisorsThatCanApply
3 对作用在该 bean 上的切面进行排序 sortAdvisors

@Aspect 的使用

@Component
@Aspect
public class AspectAnnotation {

	@Pointcut("execution(public * com.aop.service.*.*(..))")
	public void pc1(){}
	
	
	
	@Around("pc1()")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
	    System.out.println("=========AspectAnnotation around前置通知=========");
	    //可以通过下面的方法拿到入参
	    //Object[] args = joinPoint.getArgs();
	    Object result = joinPoint.proceed();
	    System.out.println("=========AspectAnnotation around后置通知=========");
	
	    return result;

	//如果方法上有@ReturnValue(name = "returnValue")注解,可以拿到返回值
	//@ReturnValue是自定义的
    @AfterReturning(value = "@annotation(returnValue)",returning = "retVal")
    public void afterReturning(JoinPoint joinPoint, ReturnValue returnValue, Object retVal) {
        System.out.println("==============AspectAnnotation 后置通知  拿返回值=========" + retVal);
    }   
}

跟源码

类AbstractAutoProxyCreator
在这里插入图片描述

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

跟 findEligibleAdvisors:

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
	//找到候选的切面,其实就是一个寻找所有有@Aspect注解的过程,把工程中所有有这个注解的类封装成Advisor返回
	List<Advisor> candidateAdvisors = findCandidateAdvisors();

	//判断候选的切面是否作用在当前beanClass上面,就是一个匹配过程。现在就是一个匹配
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	extendAdvisors(eligibleAdvisors);
	if (!eligibleAdvisors.isEmpty()) {
		//对有@Order@Priority进行排序
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	return eligibleAdvisors;
}

跟 findCandidateAdvisors:
类 AnnotationAwareAspectJAutoProxyCreator

@Override
protected List<Advisor> findCandidateAdvisors() {
	//可以不看
	// Add all the Spring advisors found according to superclass rules.
	List<Advisor> advisors = super.findCandidateAdvisors();
	// Build Advisors for all AspectJ aspects in the bean factory.
	//主要看这里,创建候选的切面
	if (this.aspectJAdvisorsBuilder != null) {
		advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
	}
	return advisors;
}

跟 buildAspectJAdvisors:
类 BeanFactoryAspectJAdvisorsBuilder

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:
类 AspectJAdvisorFactory
在这里插入图片描述
类 ReflectiveAspectJAdvisorFactory

@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
	//从工厂中获取有@Aspect注解的类Class
	Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
	//从工厂中获取有@Aspect注解的类的名称
	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)) {

		//非常重要重点看看,重要程度 5
		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()) {
		//判断属性上是否有DeclareParents注解,如果有返回切面
		Advisor advisor = getDeclareParentsAdvisor(field);
		if (advisor != null) {
			advisors.add(advisor);
		}
	}

	return advisors;
}

跟 getAdvisor:

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

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

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

	//创建Advisor切面类,这才是真正的切面类,一个切面类里面肯定要有1、pointCut 2、advice
	//这里pointCut是expressionPointcut, advice 增强方法是 candidateAdviceMethod
	//见 3.1.2
	return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
			this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

3.1.1 getPointcut

@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
	//从候选的增强方法里面 candidateAdviceMethod  找有有注解
	//Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
	//并把注解信息封装成AspectJAnnotation对象
	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:

@SuppressWarnings("unchecked")
@Nullable
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
	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;
}

在这里插入图片描述

3.1.2 InstantiationModelAwarePointcutAdvisorImpl

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

	this.declaredPointcut = declaredPointcut;
	this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
	this.methodName = aspectJAdviceMethod.getName();
	this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
	this.aspectJAdviceMethod = aspectJAdviceMethod;
	this.aspectJAdvisorFactory = aspectJAdvisorFactory;
	this.aspectInstanceFactory = aspectInstanceFactory;
	this.declarationOrder = declarationOrder;
	this.aspectName = aspectName;

	if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
		// Static part of the pointcut is a lazy type.
		Pointcut preInstantiationPointcut = Pointcuts.union(
				aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);

		// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
		// If it's not a dynamic pointcut, it may be optimized out
		// by the Spring AOP infrastructure after the first evaluation.
		this.pointcut = new PerTargetInstantiationModelPointcut(
				this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
		this.lazy = true;
	}
	else {
		// A singleton aspect.
		this.pointcut = this.declaredPointcut;
		this.lazy = false;
		//这个方法重点看看,创建advice对象
		this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
	}
}

跟 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:
类 AspectJAdvisorFactory
在这里插入图片描述
类 ReflectiveAspectJAdvisorFactory

@Override
@Nullable
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);
	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;

	//根据不同的注解类型创建不同的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);
	String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
	if (argNames != null) {
		springAdvice.setArgumentNamesFromStringArray(argNames);
	}

	//计算argNames和类型的对应关系
	springAdvice.calculateArgumentBindings();

	return springAdvice;
}

在这里插入图片描述

发布了144 篇原创文章 · 获赞 250 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44367006/article/details/104571284
今日推荐