文章结构

  1. postProcessAfterInstantiation开篇
  2. 所有的bean在初始化之后都会调用这个方法
  3. 在这里获取到之前加载到的所有的Advisor,和类的所有方法一一匹配
  4. 当类具有匹配Advisor的时候就可以为这个类生成具体的代理了

在之前的2篇文章:AOP源码分析(一)AOP源码分析(二)
中,我们搭建了SpringAOP源码分析的环境,介绍了@EnableAspectJAutoProxy注解和postProcessBeforeInstantiation方法是如何加载所有Advisor的。本篇文章则将描述一下AOP中剩余的实现逻辑

postProcessAfterInitialization

这个方法是在bean实例化之后调用的,它是适用于所有需要被代理的类的

  1. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  2. if (bean != null) {
  3. Object cacheKey = getCacheKey(bean.getClass(), beanName);
  4. if (!this.earlyProxyReferences.contains(cacheKey)) {
  5. //往下看
  6. return wrapIfNecessary(bean, beanName, cacheKey);
  7. }
  8. }
  9. return bean;
  10. }
  11. protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
  12. //如果已经处理过
  13. if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
  14. return bean;
  15. }
  16. //如果当前类是增强类
  17. if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
  18. return bean;
  19. }
  20. //查看类是否是基础设施类,或者是否被排除
  21. if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
  22. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  23. return bean;
  24. }
  25. //校验此类是否应该被代理,获取这个类的Advisor
  26. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
  27. //如果获取到了Advisor则需要针对Advisor创建代理
  28. if (specificInterceptors != DO_NOT_PROXY) {
  29. this.advisedBeans.put(cacheKey, Boolean.TRUE);
  30. //创建代理
  31. Object proxy = createProxy(
  32. bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
  33. this.proxyTypes.put(cacheKey, proxy.getClass());
  34. return proxy;
  35. }
  36. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  37. return bean;
  38. }

上方这段代理一共有两个重点,getAdvicesAndAdvisorsForBeancreateProxy这两个方法

获取Advisors

  1. protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
  2. //往下看
  3. List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
  4. if (advisors.isEmpty()) {
  5. return DO_NOT_PROXY;
  6. }
  7. return advisors.toArray();
  8. }
  9. protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
  10. //获取容器中的所有Advisor
  11. List<Advisor> candidateAdvisors = findCandidateAdvisors();
  12. //验证beanClass是否该被代理,如果应该,则返回适用于这个bean的Advisor
  13. List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
  14. extendAdvisors(eligibleAdvisors);
  15. if (!eligibleAdvisors.isEmpty()) {
  16. eligibleAdvisors = sortAdvisors(eligibleAdvisors);
  17. }
  18. return eligibleAdvisors;
  19. }

上方这个获取Advisor又分成了2部分,获取全部和根据全部处理bean相关的

获取全部Advisor

上一篇postProcessBeforeInstantiation的也有这个过程

  1. protected List<Advisor> findCandidateAdvisors() {
  2. // 调用父类的方法加载配置文件中的AOP声明(注解与XML都存在的时候)
  3. List<Advisor> advisors = super.findCandidateAdvisors();
  4. //往下看
  5. if (this.aspectJAdvisorsBuilder != null) {
  6. advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
  7. }
  8. return advisors;
  9. }

下面的方法就是获取所有的Advisor的代码实现了,方法比较长,不过主要逻辑很少。
1.获取所有beanName
2.找出所有标记Aspect注解的类
3.对标记Aspect的类提取Advisor

  1. public List<Advisor> buildAspectJAdvisors() {
  2. List<String> aspectNames = this.aspectBeanNames;
  3. if (aspectNames == null) {
  4. synchronized (this) {
  5. aspectNames = this.aspectBeanNames;
  6. if (aspectNames == null) {
  7. List<Advisor> advisors = new LinkedList<>();
  8. aspectNames = new LinkedList<>();
  9. //获取所有的bean
  10. String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
  11. this.beanFactory, Object.class, true, false);
  12. for (String beanName : beanNames) {
  13. //校验不合法的类,Spring的一个扩展点,可以从子类中做排除切面的操作
  14. if (!isEligibleBean(beanName)) {
  15. continue;
  16. }
  17. //获取bean的类型
  18. Class<?> beanType = this.beanFactory.getType(beanName);
  19. if (beanType == null) {
  20. continue;
  21. }
  22. //是否带有Aspect注解
  23. if (this.advisorFactory.isAspect(beanType)) {
  24. aspectNames.add(beanName);
  25. AspectMetadata amd = new AspectMetadata(beanType, beanName);
  26. if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
  27. MetadataAwareAspectInstanceFactory factory =
  28. new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
  29. //解析所有的Advisor方法,下面说
  30. List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
  31. if (this.beanFactory.isSingleton(beanName)) {
  32. this.advisorsCache.put(beanName, classAdvisors);
  33. }
  34. else {
  35. this.aspectFactoryCache.put(beanName, factory);
  36. }
  37. advisors.addAll(classAdvisors);
  38. }
  39. else {
  40. if (this.beanFactory.isSingleton(beanName)) {
  41. throw new IllegalArgumentException("Bean with name '" + beanName +
  42. "' is a singleton, but aspect instantiation model is not singleton");
  43. }
  44. MetadataAwareAspectInstanceFactory factory =
  45. new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
  46. this.aspectFactoryCache.put(beanName, factory);
  47. advisors.addAll(this.advisorFactory.getAdvisors(factory));
  48. }
  49. }
  50. }
  51. this.aspectBeanNames = aspectNames;
  52. return advisors;
  53. }
  54. }
  55. }
  56. if (aspectNames.isEmpty()) {
  57. return Collections.emptyList();
  58. }
  59. List<Advisor> advisors = new LinkedList<>();
  60. for (String aspectName : aspectNames) {
  61. List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
  62. if (cachedAdvisors != null) {
  63. advisors.addAll(cachedAdvisors);
  64. }
  65. else {
  66. MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
  67. advisors.addAll(this.advisorFactory.getAdvisors(factory));
  68. }
  69. }
  70. return advisors;
  71. }

接下来就是各个Advisor的获取方法的实现

  1. public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
  2. //获取所有Aspect类、类名称、并校验
  3. Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
  4. String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
  5. validate(aspectClass);
  6. MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
  7. new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
  8. List<Advisor> advisors = new LinkedList<>();
  9. //取出类的所有方法
  10. for (Method method : getAdvisorMethods(aspectClass)) {
  11. //获取Advisor方法,往下看
  12. Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
  13. if (advisor != null) {
  14. advisors.add(advisor);
  15. }
  16. }
  17. // 如果需要增强且配置了延迟增强则在第一个位置添加同步实例化Advisor方法
  18. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
  19. Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
  20. advisors.add(0, instantiationAdvisor);
  21. }
  22. // 获取属性中配置DeclareParents注解的Advisor
  23. for (Field field : aspectClass.getDeclaredFields()) {
  24. Advisor advisor = getDeclareParentsAdvisor(field);
  25. if (advisor != null) {
  26. advisors.add(advisor);
  27. }
  28. }
  29. return advisors;
  30. }

普通Advisor的获取

  1. public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
  2. int declarationOrderInAspect, String aspectName) {
  3. validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
  4. //获取切点
  5. AspectJExpressionPointcut expressionPointcut = getPointcut(
  6. candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
  7. if (expressionPointcut == null) {
  8. return null;
  9. }
  10. //根据切点生成Advisor
  11. return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
  12. this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
  13. }

上方代码又分为了两部分,先看一下切点信息的获取

  1. public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
  2. Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
  3. MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
  4. this.declaredPointcut = declaredPointcut;
  5. this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
  6. this.methodName = aspectJAdviceMethod.getName();
  7. this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
  8. this.aspectJAdviceMethod = aspectJAdviceMethod;
  9. this.aspectJAdvisorFactory = aspectJAdvisorFactory;
  10. this.aspectInstanceFactory = aspectInstanceFactory;
  11. this.declarationOrder = declarationOrder;
  12. this.aspectName = aspectName;
  13. if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
  14. Pointcut preInstantiationPointcut = Pointcuts.union(
  15. aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
  16. this.pointcut = new PerTargetInstantiationModelPointcut(
  17. this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
  18. this.lazy = true;
  19. }
  20. else {
  21. this.pointcut = this.declaredPointcut;
  22. this.lazy = false;
  23. //初始化对应的Advisor器,重点
  24. this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
  25. }
  26. }

到这里之后获取所有的Advisor这个流程就快要完毕了

  1. private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
  2. //往下看
  3. Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
  4. this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
  5. return (advice != null ? advice : EMPTY_ADVICE);
  6. }
  7. public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
  8. MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
  9. Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
  10. validate(candidateAspectClass);
  11. AspectJAnnotation<?> aspectJAnnotation =
  12. AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
  13. if (aspectJAnnotation == null) {
  14. return null;
  15. }
  16. if (!isAspect(candidateAspectClass)) {
  17. throw new AopConfigException("Advice must be declared inside an aspect type: " +
  18. "Offending method '" + candidateAdviceMethod + "' in class [" +
  19. candidateAspectClass.getName() + "]");
  20. }
  21. if (logger.isDebugEnabled()) {
  22. logger.debug("Found AspectJ method: " + candidateAdviceMethod);
  23. }
  24. AbstractAspectJAdvice springAdvice;
  25. //根据不同的注解类型封装不同的Advisor器
  26. switch (aspectJAnnotation.getAnnotationType()) {
  27. case AtBefore:
  28. springAdvice = new AspectJMethodBeforeAdvice(
  29. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  30. break;
  31. case AtAfter:
  32. springAdvice = new AspectJAfterAdvice(
  33. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  34. break;
  35. case AtAfterReturning:
  36. springAdvice = new AspectJAfterReturningAdvice(
  37. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  38. AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
  39. if (StringUtils.hasText(afterReturningAnnotation.returning())) {
  40. springAdvice.setReturningName(afterReturningAnnotation.returning());
  41. }
  42. break;
  43. case AtAfterThrowing:
  44. springAdvice = new AspectJAfterThrowingAdvice(
  45. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  46. AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
  47. if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
  48. springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
  49. }
  50. break;
  51. case AtAround:
  52. springAdvice = new AspectJAroundAdvice(
  53. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  54. break;
  55. case AtPointcut:
  56. if (logger.isDebugEnabled()) {
  57. logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
  58. }
  59. return null;
  60. default:
  61. throw new UnsupportedOperationException(
  62. "Unsupported advice type on method: " + candidateAdviceMethod);
  63. }
  64. springAdvice.setAspectName(aspectName);
  65. springAdvice.setDeclarationOrder(declarationOrder);
  66. String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
  67. if (argNames != null) {
  68. springAdvice.setArgumentNamesFromStringArray(argNames);
  69. }
  70. springAdvice.calculateArgumentBindings();
  71. return springAdvice;
  72. }

获取匹配Advisor

经过上方的长篇大论,我们终于完成了所有的Advisor器的解析,还记得刚才的方法走到哪了么

  1. protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
  2. //获取全部Advisor
  3. List<Advisor> candidateAdvisors = findCandidateAdvisors();
  4. List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
  5. extendAdvisors(eligibleAdvisors);
  6. if (!eligibleAdvisors.isEmpty()) {
  7. eligibleAdvisors = sortAdvisors(eligibleAdvisors);
  8. }
  9. return eligibleAdvisors;
  10. }

接下来看看怎么为当前的Bean匹配自己的增强吧

  1. protected List<Advisor> findAdvisorsThatCanApply(
  2. List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
  3. ProxyCreationContext.setCurrentProxiedBeanName(beanName);
  4. try {
  5. //往下看
  6. return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
  7. }
  8. finally {
  9. ProxyCreationContext.setCurrentProxiedBeanName(null);
  10. }
  11. }
  12. public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
  13. if (candidateAdvisors.isEmpty()) {
  14. return candidateAdvisors;
  15. }
  16. List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
  17. for (Advisor candidate : candidateAdvisors) {
  18. //处理引介Advisor,重点,再往下看
  19. if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
  20. eligibleAdvisors.add(candidate);
  21. }
  22. }
  23. boolean hasIntroductions = !eligibleAdvisors.isEmpty();
  24. for (Advisor candidate : candidateAdvisors) {
  25. if (candidate instanceof IntroductionAdvisor) {
  26. continue;
  27. }
  28. //对普通bean的处理
  29. if (canApply(candidate, clazz, hasIntroductions)) {
  30. eligibleAdvisors.add(candidate);
  31. }
  32. }
  33. return eligibleAdvisors;
  34. }

引介Advisor与普通bean的处理最后都是进的同一个方法,只不过是引介Advisor的第三个参数默认使用的false

  1. public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
  2. //如果存在排除的配置
  3. if (advisor instanceof IntroductionAdvisor) {
  4. return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
  5. }
  6. else if (advisor instanceof PointcutAdvisor) {
  7. PointcutAdvisor pca = (PointcutAdvisor) advisor;
  8. //往下看
  9. return canApply(pca.getPointcut(), targetClass, hasIntroductions);
  10. }
  11. else {
  12. return true;
  13. }
  14. }
  15. public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
  16. Assert.notNull(pc, "Pointcut must not be null");
  17. //切点上是否存在排除类的配置
  18. if (!pc.getClassFilter().matches(targetClass)) {
  19. return false;
  20. }
  21. //验证注解的作用域是否可以作用于方法上
  22. MethodMatcher methodMatcher = pc.getMethodMatcher();
  23. if (methodMatcher == MethodMatcher.TRUE) {
  24. return true;
  25. }
  26. IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
  27. if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
  28. introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
  29. }
  30. Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
  31. classes.add(targetClass);
  32. for (Class<?> clazz : classes) {
  33. Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
  34. for (Method method : methods) {
  35. //获取类所实现的所有接口和所有类层级的方法,循环验证
  36. if ((introductionAwareMethodMatcher != null &&
  37. introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
  38. methodMatcher.matches(method, targetClass)) {
  39. return true;
  40. }
  41. }
  42. }
  43. return false;
  44. }

现在所有的bean对应的Advisor都已经获取到了,那么就可以根据类的所有Advisor数组创建代理

创建代理

回到最上方开始获取Advisor的地方,当Advisor获取到之后就可以执行下面这个操作了

  1. protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
  2. @Nullable Object[] specificInterceptors, TargetSource targetSource) {
  3. if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
  4. AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
  5. }
  6. ProxyFactory proxyFactory = new ProxyFactory();
  7. 使用proxyFactory对象copy当前类中的相关属性
  8. proxyFactory.copyFrom(this);
  9. //判断是否使用Cglib动态代理
  10. if (!proxyFactory.isProxyTargetClass()) {
  11. //如果配置开启使用则直接设置开启
  12. if (shouldProxyTargetClass(beanClass, beanName)) {
  13. proxyFactory.setProxyTargetClass(true);
  14. }
  15. else {
  16. //如果没有配置开启则判断bean是否有合适的接口使用JDK的动态代理(JDK动态代理必须是带有接口的类,如果类没有实现任何接口则只能使用Cglib动态代理)
  17. //关于代理的基础知识可以参考我的另一篇文章:https://mp.weixin.qq.com/s/1DRmvuky5_NMRcH-toTLqQ
  18. evaluateProxyInterfaces(beanClass, proxyFactory);
  19. }
  20. }
  21. //添加所有Advisor
  22. Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
  23. proxyFactory.addAdvisors(advisors);
  24. //设置要代理的类
  25. proxyFactory.setTargetSource(targetSource);
  26. //Spring的一个扩展点,默认实现为空。留给我们在需要对代理进行特殊操作的时候实现
  27. customizeProxyFactory(proxyFactory);
  28. proxyFactory.setFrozen(this.freezeProxy);
  29. if (advisorsPreFiltered()) {
  30. proxyFactory.setPreFiltered(true);
  31. }
  32. //使用代理工厂获取代理对象
  33. return proxyFactory.getProxy(getProxyClassLoader());
  34. }

获取代理对象

  1. public Object getProxy(@Nullable ClassLoader classLoader) {
  2. return createAopProxy().getProxy(classLoader);
  3. }
  4. protected final synchronized AopProxy createAopProxy() {
  5. if (!this.active) {
  6. activate();
  7. }
  8. return getAopProxyFactory().createAopProxy(this);
  9. }
  10. public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
  11. if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
  12. Class<?> targetClass = config.getTargetClass();
  13. if (targetClass == null) {
  14. throw new AopConfigException("TargetSource cannot determine target class: " +
  15. "Either an interface or a target is required for proxy creation.");
  16. }
  17. if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
  18. return new JdkDynamicAopProxy(config);
  19. }
  20. return new ObjenesisCglibAopProxy(config);
  21. }
  22. else {
  23. return new JdkDynamicAopProxy(config);
  24. }
  25. }

Advisor何时调用

代理创建出来了,那么我们的前置增强、后置增强、环绕增强等是如何在代理中体现的呢,对代理模式还不熟悉的同学一定要先看一下这篇文章呦:https://mp.weixin.qq.com/s/1DRmvuky5_NMRcH-toTLqQ
这里就简单看一下JDK动态代理的实现吧

  1. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  2. MethodInvocation invocation;
  3. Object oldProxy = null;
  4. boolean setProxyContext = false;
  5. TargetSource targetSource = this.advised.targetSource;
  6. Object target = null;
  7. try {
  8. //equals方法处理
  9. if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
  10. return equals(args[0]);
  11. }
  12. //hash代码处理
  13. else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
  14. return hashCode();
  15. }
  16. else if (method.getDeclaringClass() == DecoratingProxy.class) {
  17. return AopProxyUtils.ultimateTargetClass(this.advised);
  18. }
  19. else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
  20. method.getDeclaringClass().isAssignableFrom(Advised.class)) {
  21. // Service invocations on ProxyConfig with the proxy config...
  22. return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
  23. }
  24. Object retVal;
  25. //如果配置内部方法调用的Advisor
  26. if (this.advised.exposeProxy) {
  27. oldProxy = AopContext.setCurrentProxy(proxy);
  28. setProxyContext = true;
  29. }
  30. target = targetSource.getTarget();
  31. Class<?> targetClass = (target != null ? target.getClass() : null);
  32. // 获取当前方法的拦截器链
  33. List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
  34. if (chain.isEmpty()) {
  35. //如果没有拦截器直接调用切点方法
  36. Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
  37. retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
  38. }
  39. else {
  40. invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
  41. //执行拦截器链,重点,往下看
  42. retVal = invocation.proceed();
  43. }
  44. Class<?> returnType = method.getReturnType();
  45. //返回结果
  46. if (retVal != null && retVal == target &&
  47. returnType != Object.class && returnType.isInstance(proxy) &&
  48. !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
  49. retVal = proxy;
  50. }
  51. else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
  52. throw new AopInvocationException(
  53. "Null return value from advice does not match primitive return type for: " + method);
  54. }
  55. return retVal;
  56. }
  57. finally {
  58. if (target != null && !targetSource.isStatic()) {
  59. targetSource.releaseTarget(target);
  60. }
  61. if (setProxyContext) {
  62. AopContext.setCurrentProxy(oldProxy);
  63. }
  64. }
  65. }

看完上方的代码,可以猜到,所有的Advisor都在这个拦截器里面了,那么这个拦截器又是如何实现的呢

  1. public Object proceed() throws Throwable {
  2. // 执行完所有的Advisor后执行切点方法
  3. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
  4. return invokeJoinpoint();
  5. }
  6. //获取下一个要执行的拦截器
  7. Object interceptorOrInterceptionAdvice =
  8. this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
  9. if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
  10. InterceptorAndDynamicMethodMatcher dm =
  11. (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
  12. if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
  13. return dm.interceptor.invoke(this);
  14. }
  15. else {
  16. // 递归调用
  17. // Dynamic matching failed.
  18. // Skip this interceptor and invoke the next in the chain.
  19. return proceed();
  20. }
  21. }
  22. else {
  23. // It's an interceptor, so we just invoke it: The pointcut will have
  24. // been evaluated statically before this object was constructed.
  25. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
  26. }
  27. }

至此SpringAOP的源码解析已经完成