Spring AOP系列学习笔记三:AOP注解原理分析

原文地址程序员囧辉大佬

AOP系列文章链接地址

Spring AOP系列学习笔记一:AOP简介
Spring AOP系列学习笔记二:AOP入口分析
Spring AOP系列学习笔记三:AOP注解原理分析
Spring AOP系列学习笔记四:AOP具体调用流程分析

前言

前面我们介绍了aop基于xml和注解的入口,下面我们正式进入解析的过程。在解析BeanPostProcessor 接口的时候已经介绍过了,在bean初始化的前后会分别调用postProcessBeforeInitialization和postProcessAfterInitialization,AnnotationAwareAspectJAutoProxyCreator或者其父类实现了BeanPostProcessor接口,下面进入该方法。

代码块一:postProcessAfterInitialization

	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
		if (bean != null) {
			1、从缓存中获取
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (!this.earlyProxyReferences.contains(cacheKey)) {
				2、对bean进行封装
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

2、对bean进行分装见代码块二

代码块二:wrapIfNecessary

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		1、判断targetSourcedBeans有无缓存
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		2、判断advisedBeans是否有缓存
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		3、当前bean是Aop的基础类,或者应该跳过创建代理
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.
		4、获取当前bean的增强器,也可以理解为切面(自己的理解)
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			4.1、创建代理,这儿SingletonTargetSource存放的是被代理对象
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			4.2、存放到缓存中
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}
		5、走到这儿,说明要代理的bean已经生成代理或者没有代理,标记为无需处理。
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

4、获取当前bean的增强器,也可以理解为切面(自己的理解)见代码块三
4.1、创建代理 见代码块十六

代码块三:getAdvicesAndAdvisorsForBean

	protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
		1、查找符合条件的代理类
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}

1、查找符合条件的代理类见代码块四

代码块四:findEligibleAdvisors

	protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		1、查找所有的所有代理类(AdvisorList<Advisor> candidateAdvisors = findCandidateAdvisors();
		2、筛选出符合当前bean的代理类
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		3、扩展方法
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			4、进行排序
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

1、查找所有的所有代理类(Advisor)见代码块五
2、筛选出符合当前bean的代理类见代码块十四

代码块五:findCandidateAdvisors

	@Override
	protected List<Advisor> findCandidateAdvisors() {
		// Add all the Spring advisors found according to superclass rules.
		1、找到所有的Spring顾问
		List<Advisor> advisors = super.findCandidateAdvisors();
		// Build Advisors for all AspectJ aspects in the bean factory.
		if (this.aspectJAdvisorsBuilder != null) {
			2、为bean工厂所有的AspectJ方面构建advisor
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		return advisors;
	}

1、找到所有的Advisor 见代码块六
2、为bean工厂所有的AspectJ方面构建advisor见代码块七

代码块六:findCandidateAdvisors

protected List<Advisor> findCandidateAdvisors() {
    return this.advisorRetrievalHelper.findAdvisorBeans();
}
 
public List<Advisor> findAdvisorBeans() {
    // 1.确认advisor的beanName列表,优先从缓存中拿
    String[] advisorNames = null;
    synchronized (this) {
        advisorNames = this.cachedAdvisorBeanNames;
        if (advisorNames == null) {
            //  1.1 如果缓存为空,则获取class类型为Advisor的所有bean名称
            advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                    this.beanFactory, Advisor.class, true, false);
            this.cachedAdvisorBeanNames = advisorNames;
        }
    }
    if (advisorNames.length == 0) {
        return new LinkedList<Advisor>();
    }
 
    // 2.遍历处理advisorNames
    List<Advisor> advisors = new LinkedList<Advisor>();
    for (String name : advisorNames) {
        if (isEligibleBean(name)) {
            // 2.1 跳过当前正在创建的advisor
            if (this.beanFactory.isCurrentlyInCreation(name)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Skipping currently created advisor '" + name + "'");
                }
            } else {
                try {
                    // 2.2 通过beanName获取对应的bean对象,并添加到advisors
                    advisors.add(this.beanFactory.getBean(name, Advisor.class));
                } catch (BeanCreationException ex) {
                    Throwable rootCause = ex.getMostSpecificCause();
                    if (rootCause instanceof BeanCurrentlyInCreationException) {
                        BeanCreationException bce = (BeanCreationException) rootCause;
                        if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {
                            if (logger.isDebugEnabled()) {
                                logger.debug("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;
                }
            }
        }
    }
    // 3.返回符合条件的advisor列表
    return advisors;
}

代码块七:buildAspectJAdvisors

public List<Advisor> buildAspectJAdvisors() {
		List<String> aspectNames = this.aspectBeanNames;
		1、先验证缓存中是否已经存在
		if (aspectNames == null) {
			synchronized (this) {
				aspectNames = this.aspectBeanNames;
				if (aspectNames == null) {
					List<Advisor> advisors = new LinkedList<>();
					aspectNames = new LinkedList<>();
					2、获取所有的beanName
					String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
							this.beanFactory, Object.class, true, false);
					for (String beanName : beanNames) {
						3.1、不合法的beanName则跳过,默认返回true
						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.
						3.2、获取beanName对应的类型
						Class<?> beanType = this.beanFactory.getType(beanName);
						if (beanType == null) {
							continue;
						}
						3.3、该类是否存在@Aspect注解
						if (this.advisorFactory.isAspect(beanType)) {
							4、使用了注解,添加到缓存中
							aspectNames.add(beanName);
							4.1、构建一个切面的元数据
							AspectMetadata amd = new AspectMetadata(beanType, beanName);
							4.2、判断切面per-clause是否是单例的
							if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
								4.3、使用BeanFactory和beanName创建一个BeanFactoryAspectInstanceFactory,主要用来创建切面对象实例
								MetadataAwareAspectInstanceFactory factory =
										new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
								4.4、解析切面的增强方法
								List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
								4.5、如果切面是单例的,则直接放到缓存中
								if (this.beanFactory.isSingleton(beanName)) {
									this.advisorsCache.put(beanName, classAdvisors);
								}
								else {
									4.6、如果切面是多例的则,先放入到factory缓存,每次获取的时候用factory去解析
									this.aspectFactoryCache.put(beanName, factory);
								}
								4.7、将解析的增强器添加到advisors,后面作为方法的返回值
								advisors.addAll(classAdvisors);
							}
							else {
								// Per target or per this.
								4.8、如果per-clause是多例的,但是切面beanName是单例的,直接抛出异常
								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);
								4.9、都是多例,则先放入到factory缓存中,以后从factory解析使用
								this.aspectFactoryCache.put(beanName, factory);
								4.10、解析标记AspectJ注解中的增强方法,并添加到advisors中
								advisors.addAll(this.advisorFactory.getAdvisors(factory));
							}
						}
					}
					this.aspectBeanNames = aspectNames;
					return advisors;
				}
			}
		}

		5、走到这儿,说明aspectNames不是null,已经解析过了
		if (aspectNames.isEmpty()) {
			return Collections.emptyList();
		}
		List<Advisor> advisors = new LinkedList<>();
		for (String aspectName : aspectNames) {
			5.1、从上面放入的缓存中获取,在这个缓存中说明都已经解析过了,直接放入到advisors
			List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
			if (cachedAdvisors != null) {
				advisors.addAll(cachedAdvisors);
			}
			else {
				5.2、从aspectFactoryCache中拿到缓存的factory,然后解析出增强器,添加到结果中
				MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
				advisors.addAll(this.advisorFactory.getAdvisors(factory));
			}
		}
		return advisors;
	}

4.4、解析切面的增强方法见代码块八

代码块八:getAdvisors

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
		1、获取当前的切面类
		Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
		2、获取切面类名字
		String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
		3、校验切面类
		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 LinkedList<>();
		4、获取切面类中的方法(也就是我们用来进行逻辑增强的方法,被@Around@After等注解修饰的方法,使用@Pointcut的方法不处理)
		for (Method method : getAdvisorMethods(aspectClass)) {
			4.1、处理method
			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()) {
			5、如果寻找的增强器不为空而且又配置了增强延迟初始化,那么需要在首位加入同步实例化增强器(用以保证增强使用之前的实例化)
			Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
			advisors.add(0, instantiationAdvisor);
		}

		// Find introduction fields.
		6、获取DeclareParents注解
		for (Field field : aspectClass.getDeclaredFields()) {
			Advisor advisor = getDeclareParentsAdvisor(field);
			if (advisor != null) {
				advisors.add(advisor);
			}
		}

		return advisors;
	}

4.1、处理method 见代码块九

代码块九:getAdvisor

	public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
			int declarationOrderInAspect, String aspectName) {
		1、校验切面类
		validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
		2、获取切点表达式,如:@Around("execution(* com.joonwhee.open.aop.*.*(..))")
		AspectJExpressionPointcut expressionPointcut = getPointcut(
				candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
		3、如果expressionPointcut为null,则直接返回null
		if (expressionPointcut == null) {
			return null;
		}
		4、进行包装,返回增强器
		return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
				this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
	}

2、获取切点表达式 见代码块十
4、进行包装,返回增强器见代码块十二

代码块十:getPointcut

private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
     1.查找并返回给定方法的第一个AspectJ注解(@Before, @Around, @After, @AfterReturning, @AfterThrowing, @Pointcut)
     因为我们之前把@Pointcut注解的方法跳过了,所以这边必然不会获取到@Pointcut注解
    AspectJAnnotation<?> aspectJAnnotation =
            AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
     2.如果方法没有使用AspectJ的注解,则返回null
    if (aspectJAnnotation == null) {
        return null;
    }
     3.使用AspectJExpressionPointcut实例封装获取的信息
    AspectJExpressionPointcut ajexp =
            new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
    提取得到的注解中的表达式,
    例如:@Around("execution(* com.joonwhee.open.aop.*.*(..))"),得到:execution(* com.joonwhee.open.aop.*.*(..))
    ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
    ajexp.setBeanFactory(this.beanFactory);
    return ajexp;
}

1.查找并返回给定方法的AspectJ注解见代码块十一

代码块十一:findAspectJAnnotationOnMethod

	protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
		1、设置要查找的注解类
		Class<?>[] classesToLookFor = new Class<?>[] {
				Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
		2、查找方法上是否存在当前遍历的注解,如果有则返回
		for (Class<?> c : classesToLookFor) {
			AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);
			if (foundAnnotation != null) {
				return foundAnnotation;
			}
		}
		return null;
	}

代码块十二:new InstantiationModelAwarePointcutAdvisorImpl

public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
                                                  Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
                                                  MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
    1.简单的将信息封装在类的实例中
    this.declaredPointcut = declaredPointcut;
    this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
    this.methodName = aspectJAdviceMethod.getName();
    this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
    aspectJAdviceMethod保存的是我们用来进行逻辑增强的方法(@Around@After等修饰的方法)
    this.aspectJAdviceMethod = aspectJAdviceMethod;
    this.aspectJAdvisorFactory = aspectJAdvisorFactory;
    this.aspectInstanceFactory = aspectInstanceFactory;
    this.declarationOrder = declarationOrder;
    this.aspectName = aspectName;
    2.是否需要延迟实例化
    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;
        3.实例化增强器:根据注解中的信息初始化对应的增强器
        this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
    }
}

3.实例化增强器:根据注解中的信息初始化对应的增强器见代码块十三

代码块十三:instantiateAdvice

	private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
		1、获取切面的增强方法
		Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
				this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
		return (advice != null ? advice : EMPTY_ADVICE);
	}
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
			MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
		1、获取切面类
		Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
		2、校验切面类
		validate(candidateAspectClass);
		3、返回起一个AspectJ注解如:Before, Around, After, AfterReturning, AfterThrowing, 在这儿获取不到point
		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;
		4、判断使用的注解,生成对应的增强包装类
		switch (aspectJAnnotation.getAnnotationType()) {
			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;
			case AtAround:
				springAdvice = new AspectJAroundAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			case AtPointcut:
				if (logger.isDebugEnabled()) {
					logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
				}
				return null;
			default:
				throw new UnsupportedOperationException(
						"Unsupported advice type on method: " + candidateAdviceMethod);
		}

		// Now to configure the advice...
		5、配置增强器
		springAdvice.setAspectName(aspectName);
		springAdvice.setDeclarationOrder(declarationOrder);
		String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
		if (argNames != null) {
			springAdvice.setArgumentNamesFromStringArray(argNames);
		}
		springAdvice.calculateArgumentBindings();
		return springAdvice;
	}

代码块十四:findAdvisorsThatCanApply

	protected List<Advisor> findAdvisorsThatCanApply(
			List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

		ProxyCreationContext.setCurrentProxiedBeanName(beanName);
		try {
			1、进行筛选,获取符合条件的切面
			return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
		}
		finally {
			ProxyCreationContext.setCurrentProxiedBeanName(null);
		}
	}
		public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
		if (candidateAdvisors.isEmpty()) {
			return candidateAdvisors;
		}
		List<Advisor> eligibleAdvisors = new LinkedList<>();
		for (Advisor candidate : candidateAdvisors) {
			1、首先处理引介增强(@DeclareParents)用的比较少可以忽略
			if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
				eligibleAdvisors.add(candidate);
			}
		}
		boolean hasIntroductions = !eligibleAdvisors.isEmpty();
		2、遍历所有的切面
		for (Advisor candidate : candidateAdvisors) {
			2.1、引介增强已经处理,直接跳过
			if (candidate instanceof IntroductionAdvisor) {
				// already processed
				continue;
			}
			2.2、正常增强处理,判断当前bean是否可以应用于当前遍历的增强器
			(bean是否包含在增强器的execution指定的表达式中)
			if (canApply(candidate, clazz, hasIntroductions)) {
				eligibleAdvisors.add(candidate);
			}
		}
		return eligibleAdvisors;
	}

2.2、正常增强处理,判断当前bean是否可以应用于当前遍历的增强器见代码块十五

代码块十五:canApply

	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 pca = (PointcutAdvisor) advisor;
			1、确定切入点是否适合当前类
			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");
		1、判断当前类是否匹配表达式
		if (!pc.getClassFilter().matches(targetClass)) {
			return false;
		}
		2、如果增强方法匹配所有方法,则直接返回true
		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<>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
		classes.add(targetClass);
		for (Class<?> clazz : classes) {
			3、获取被代理类的所有方法
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			for (Method method : methods) {
				3.1、增强方法匹配不为空&&该方法符合表达式||符合方法表达式(自己没懂)
				if ((introductionAwareMethodMatcher != null &&
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
						methodMatcher.matches(method, targetClass)) {
					return true;
				}
			}
		}

		return false;
	}

代码块十六: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();
		proxyFactory.copyFrom(this);
		1、判断被代理类是基于接口代理还是类代理
		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				1.1、若基于类代理,则proxyTargetClass属性设置为true
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				1.2、评估bean的代理接口
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
		2、构建增强器
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
		3、设置被代理的类
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		4、用来控制proxyFactory被配置之后,是否还允许修改通知。默认值为false(即在代理被配置之后,不允许修改代理类的配置)
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
		5、获取代理
		return proxyFactory.getProxy(getProxyClassLoader());
	}

5、获取代理见代码块十七

代码块十七:getProxy

	public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}



protected final synchronized AopProxy createAopProxy() {
    if (!this.active) {
        // 1.激活此代理配置
        activate();
    }
    // 2.创建AopProxy
    return getAopProxyFactory().createAopProxy(this);
}
 
 
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    // 1.判断使用JDK动态代理还是Cglib代理
    // optimize:用于控制通过cglib创建的代理是否使用激进的优化策略。除非完全了解AOP如何处理代理优化,
    // 否则不推荐使用这个配置,目前这个属性仅用于cglib代理,对jdk动态代理无效
    // proxyTargetClass:默认为false,设置为true时,强制使用cglib代理,设置方式:<aop:aspectj-autoproxy proxy-target-class="true" />
    // hasNoUserSuppliedProxyInterfaces:config是否存在代理接口或者只有SpringProxy一个接口
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        // 拿到要被代理的对象的类型
        Class<?> targetClass = config.getTargetClass();
        if (targetClass == null) {
            // TargetSource无法确定目标类:代理创建需要接口或目标。
            throw new AopConfigException("TargetSource cannot determine target class: " +
                    "Either an interface or a target is required for proxy creation.");
        }
        // 要被代理的对象是接口 || targetClass是Proxy class
        // 当且仅当使用getProxyClass方法或newProxyInstance方法动态生成指定的类作为代理类时,才返回true。
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            // JDK动态代理,这边的入参config(AdvisedSupport)实际上是ProxyFactory对象
            // 具体为:AbstractAutoProxyCreator中的proxyFactory.getProxy发起的调用,在ProxyCreatorSupport使用了this作为参数,
            // 调用了的本方法,这边的this就是发起调用的proxyFactory对象,而proxyFactory对象中包含了要执行的的拦截器
            return new JdkDynamicAopProxy(config);
        }
        // Cglib代理
        return new ObjenesisCglibAopProxy(config);
    } else {
        // JDK动态代理
        return new JdkDynamicAopProxy(config);
    }
}

new JdkDynamicAopProxy和new CglibAopProxy

	public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
		Assert.notNull(config, "AdvisedSupport must not be null");
		if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
			throw new AopConfigException("No advisors and no TargetSource specified");
		}
		this.advised = config;
	}



		public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
		Assert.notNull(config, "AdvisedSupport must not be null");
		if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
			throw new AopConfigException("No advisors and no TargetSource specified");
		}
		this.advised = config;
		this.advisedDispatcher = new AdvisedDispatcher(this.advised);
	}

这儿把config都设置到了对应的代理类中。
getProxy()方法也会走对应的代理类中的方法。

JdkDynamicAopProxy&getProxy

	@Override
	public Object getProxy(@Nullable ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
		}
		1、获取被代理的所有的接口
		Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		2.通过classLoader、接口、InvocationHandler实现类,来获取到代理对象
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}

在CglibAopProxy的getProxy()方法简单介绍一下,代码主要关注一下getCallbacks()这个方法。

CglibAopProxy& getProxy

@Override
	public Object getProxy(@Nullable ClassLoader classLoader) {
		if (logger.isTraceEnabled()) {
			logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
		}

		try {
			1、获取被代理的原始类
			Class<?> rootClass = this.advised.getTargetClass();
			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
		
			Class<?> proxySuperClass = rootClass;
			2、CGLIB_CLASS_SEPARATOR 是字符串   $$
			说明当前类已经是cglib代理类了
			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...
			3、携带所有cglib所需的配置信息,后续用于反射创建代理对象
			Enhancer enhancer = createEnhancer();
			if (classLoader != null) {
				enhancer.setClassLoader(classLoader);
				if (classLoader instanceof SmartClassLoader &&
						((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
					enhancer.setUseCache(false);
				}
			}
			enhancer.setSuperclass(proxySuperClass);
			4、配置代理类需要实现的接口,一般是SpringProxyAdvised
			enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
			enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
			enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
			5、获取代理所需的所有拦截器,后续通过ProxyCallbackFilter内部类进行确定使用的具体拦截器
			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
			enhancer.setCallbackFilter(new ProxyCallbackFilter(
					this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
			enhancer.setCallbackTypes(types);

			// Generate the proxy class and create a proxy instance.
			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);
		}
	}

5、获取代理所需的所有拦截器,后续通过ProxyCallbackFilter内部类进行确定使用的具体拦截器 见代码块十六代码块十七

代码块十八 getCallbacks

获取该方法的所有拦截器

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
		// Parameters used for optimization choices...
		1、是否需要对外暴露
		boolean exposeProxy = this.advised.isExposeProxy();
		2、是否冻结
		boolean isFrozen = this.advised.isFrozen();
		3、是否是单例的
		boolean isStatic = this.advised.getTargetSource().isStatic();

		// Choose an "aop" interceptor (used for AOP calls).
		4、AOP默认的拦截器,我们自己写的大部分场景用的也都是这个拦截器
		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;
		5、是否对外暴露
		if (exposeProxy) {
			targetInterceptor = (isStatic ?
					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).
		6、直接调用目标方法
		Callback targetDispatcher = (isStatic ?
				new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());

		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.
		7、是单例的并且被冻结
		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];
				7.1、获取符合被代理方法的所有增强,这儿提前获取并封装到拦截器中了,正常是在拦截器的
					  intercept()方法内获取到调用链,就是代理生成之后无法再修改
				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;
	}

代码块十九:ProxyCallbackFilter accept()

确定具体使用哪个拦截器

@Override
public int accept(Method method) {
	1、是否被final修饰,则不代理
	if (AopUtils.isFinalizeMethod(method)) {
		logger.trace("Found finalize() method - using NO_OVERRIDE");
		return NO_OVERRIDE;
	}
	2、不透明&&方法所在类是接口&&实现了Advised
	if (!this.advised.isOpaque() && method.getDeclaringClass().isInterface() &&
			method.getDeclaringClass().isAssignableFrom(Advised.class)) {
		if (logger.isTraceEnabled()) {
			logger.trace("Method is declared on Advised interface: " + method);
		}
		return DISPATCH_ADVISED;
	}
	// We must always proxy equals, to direct calls to this.
	3、equal方法
	if (AopUtils.isEqualsMethod(method)) {
		if (logger.isTraceEnabled()) {
			logger.trace("Found 'equals' method: " + method);
		}
		return INVOKE_EQUALS;
	}
	// We must always calculate hashCode based on the proxy.
	4HashCode方法
	if (AopUtils.isHashCodeMethod(method)) {
		if (logger.isTraceEnabled()) {
			logger.trace("Found 'hashCode' method: " + method);
		}
		return INVOKE_HASHCODE;
	}
	Class<?> targetClass = this.advised.getTargetClass();
	// Proxy is not yet available, but that shouldn't matter.
	5、获取符合该方法的增强
	List<?> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
	boolean haveAdvice = !chain.isEmpty();
	boolean exposeProxy = this.advised.isExposeProxy();
	boolean isStatic = this.advised.getTargetSource().isStatic();
	boolean isFrozen = this.advised.isFrozen();
	6、有无增强
	if (haveAdvice || !isFrozen) {
		// If exposing the proxy, then AOP_PROXY must be used.
		6.1、是否对外暴露
		通过AopContext.setCurrentProxy()获取对外暴露的代理对象;
		if (exposeProxy) {
			if (logger.isTraceEnabled()) {
				logger.trace("Must expose proxy on advised method: " + method);
			}
			return AOP_PROXY;
		}
		// Check to see if we have fixed interceptor to serve this method.
		// Else use the AOP_PROXY.
		6.2、单例&&冻结&& 在getCallbacks方法中是否添加到了fixedInterceptorMap
		if (isStatic && isFrozen && this.fixedInterceptorMap.containsKey(method)) {
			if (logger.isTraceEnabled()) {
				logger.trace("Method has advice and optimizations are enabled: " + method);
			}
			// We know that we are optimizing so we can use the FixedStaticChainInterceptors.
			int index = this.fixedInterceptorMap.get(method);
			return (index + this.fixedInterceptorOffset);
		}
		else {
			if (logger.isTraceEnabled()) {
				logger.trace("Unable to apply any optimizations to advised method: " + method);
			}
			6.3、使用AOP
			return AOP_PROXY;
		}
	}
	else {
		7、没有增强
		// See if the return type of the method is outside the class hierarchy of the target type.
		// If so we know it never needs to have return type massage and can use a dispatcher.
		// If the proxy is being exposed, then must use the interceptor the correct one is already
		// configured. If the target is not static, then we cannot use a dispatcher because the
		// target needs to be explicitly released after the invocation.
		7.1、暴露当前代理类 && 代理类不是单例
		if (exposeProxy || !isStatic) {
			return INVOKE_TARGET;
		}
		Class<?> returnType = method.getReturnType();
		7.2、方法的返回值还是本身
		if (targetClass != null && returnType.isAssignableFrom(targetClass)) {
			if (logger.isTraceEnabled()) {
				logger.trace("Method return type is assignable from target type and " +
						"may therefore return 'this' - using INVOKE_TARGET: " + method);
			}
			return INVOKE_TARGET;
		}
		else {
			7.3、直接执行目标方法
			if (logger.isTraceEnabled()) {
				logger.trace("Method return type ensures 'this' cannot be returned - " +
						"using DISPATCH_TARGET: " + method);
			}
			return DISPATCH_TARGET;
		}
	}
}

最终,通过 CGLIB 代理的类被调用时,会走到对应拦截器,如常用的DynamicAdvisedInterceptor#intercept 方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值