2023-09-16
原文作者:王伟王胖胖 原文地址: https://blog.csdn.net/wangwei19871103/article/details/105208217

findCandidateAdvisors寻找通知器

上篇讲到shouldSkip的方法,里面其实挺复杂,主要就是findCandidateAdvisors方法。

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

AbstractAdvisorAutoProxyCreator的findCandidateAdvisors

首先会调用BeanFactoryAdvisorRetrievalHelper来寻找是否有Advisorbean定义。

    	protected List<Advisor> findCandidateAdvisors() {
    		Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
    		return this.advisorRetrievalHelper.findAdvisorBeans();
    	}

BeanFactoryAdvisorRetrievalHelper的findAdvisorBeans

其实就是寻找所有Advisor.classbean名字,如果存在就放入缓存,并进行创建,然后返回。

    public List<Advisor> findAdvisorBeans() {
    		// Determine list of advisor bean names, if not cached already.
    		String[] advisorNames = this.cachedAdvisorBeanNames;
    		if (advisorNames == null) {
    			// Do not initialize FactoryBeans here: We need to leave all regular beans
    			// uninitialized to let the auto-proxy creator apply to them!
    			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 {
    						advisors.add(this.beanFactory.getBean(name, Advisor.class));
    					}
    					catch (BeanCreationException ex) {
    						...
    						throw ex;
    					}
    				}
    			}
    		}
    		return advisors;
    	}

BeanFactoryAspectJAdvisorsBuilderd的buildAspectJAdvisors(重点)

这里就是复杂的地方啦,其实他做的就是寻找Aspect注解的切面对象,然后解析他的方法,通过注解来生成对应的通知器Advisor

    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<>();//切面名字列表
    					String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(//寻找所有object类型的bean定义名字
    							this.beanFactory, Object.class, true, false);
    					for (String beanName : beanNames) {//遍历获取有Aspect注解的加入到aspectNames列表
    						if (!isEligibleBean(beanName)) {
    							continue;
    						}
    
    						Class<?> beanType = this.beanFactory.getType(beanName);//获取类型,如果不存在,可能已经被代理过了
    						if (beanType == null) {
    							continue;
    						}
    						if (this.advisorFactory.isAspect(beanType)) {//是否有Aspect注解的
    							aspectNames.add(beanName);
    							AspectMetadata amd = new AspectMetadata(beanType, beanName);//创建切面元数据
    							if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {//单例
    								MetadataAwareAspectInstanceFactory factory =//创建实例工厂
    										new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
    								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;
    	}

ReflectiveAspectJAdvisorFactory的getAdvisors

首先获取切面类型,然后获取除Pointcut注解的所有方法,根据方法注解来创建Advisor通知器。

    @Override
    	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<>();
    		for (Method method : getAdvisorMethods(aspectClass)) {//获取通知器方法
    			Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);//创建Advisor
    			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.introduction处理
    		for (Field field : aspectClass.getDeclaredFields()) {
    			Advisor advisor = getDeclareParentsAdvisor(field);
    			if (advisor != null) {
    				advisors.add(advisor);
    			}
    		}
    
    		return advisors;
    	}

getAdvisorMethods获取Pointcut注解的方法

这里会后的所有不包含Pointcut注解的方法,让然后进行排序,根据这个注解顺序Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class,然后才是普通方法。

    	private List<Method> getAdvisorMethods(Class<?> aspectClass) {
    		final List<Method> methods = new ArrayList<>();
    		ReflectionUtils.doWithMethods(aspectClass, method -> {
    			// Exclude pointcuts
    			if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
    				methods.add(method);
    			}
    		}, ReflectionUtils.USER_DECLARED_METHODS);
    		methods.sort(METHOD_COMPARATOR);
    		return methods;
    	}

然后就是关键的getAdvisor方法了,这个我们后面说吧。

好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。

阅读全文