SpringAop源码阅读(一)代理类的创建过程

添加支持自动代理的核心处理类

  1. 通过@Import导入AspectJAutoProxyRegistrar

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(AspectJAutoProxyRegistrar.class)
    public @interface EnableAspectJAutoProxy {
       boolean proxyTargetClass() default false;
       boolean exposeProxy() default false;
    }
    
  2. AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar,直接看registerBeanDefinitions方法。

    class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    
       @Override
       public void registerBeanDefinitions(
             AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    
          AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
    
          AnnotationAttributes enableAspectJAutoProxy =
                AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
          if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
             AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
          }
          if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
             AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
          }
       }
    
    }
    
  3. 可以看到导入了aop的核心处理类AnnotationAwareAspectJAutoProxyCreator

    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
       return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
    }
    

实例化AOP相关类

  1. 由于AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor,关注实例化之前的处理

    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
       Object cacheKey = getCacheKey(beanClass, beanName);
    
       if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
          if (this.advisedBeans.containsKey(cacheKey)) {
             return null;
          }
          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.
       if (beanName != null) {
          TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
          if (targetSource != null) {
             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;
    }
    
  2. 进入核心处理方法shouldSkip,然后进入构建Advisors的方法buildAspectJAdvisors

    public List<Advisor> buildAspectJAdvisors() {
       List<String> aspectNames = null;
    
       synchronized (this) {
          aspectNames = this.aspectBeanNames;
          if (aspectNames == null) {
             List<Advisor> advisors = new LinkedList<Advisor>();
             aspectNames = new LinkedList<String>();
             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;
                }
                // 如果当前类是切面类
                if (this.advisorFactory.isAspect(beanType)) {
                   aspectNames.add(beanName);
                   AspectMetadata amd = new AspectMetadata(beanType, beanName);
                   if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                      MetadataAwareAspectInstanceFactory factory =
                            new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                      // 获取所有的Advisors
                      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 LinkedList<Advisor>();
       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;
    }
    
  3. 进入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 LinkedList<Advisor>();
       // 获取所有非PointCut标注的方法,进行遍历处理
       for (Method method : getAdvisorMethods(aspectClass)) {
          // 从方法中获取Advisor
          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;
    }
    
  4. 进入getAdvisor

    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;
       }
    
       return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
             this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
    }
    

private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
    // 找到方法上的注解切面相关注解
   AspectJAnnotation<?> aspectJAnnotation =
        AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
   if (aspectJAnnotation == null) {
      return null;
   }
   // 创建AspectJExpressionPointcut实例
   AspectJExpressionPointcut ajexp =
         new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
   // 设置表达式名称
   ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
   return ajexp;
}
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
   Class<?>[] classesToLookFor = new Class<?>[] {
         Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
   // 遍历所有的Advice
   for (Class<?> c : classesToLookFor) {
      AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);	  // 如果找到了Advice,则直接返回
      if (foundAnnotation != null) {
         return foundAnnotation;
      }
   }
   return null;
}
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 {
      // 非懒加载,走这里
      this.pointcut = this.declaredPointcut;
      this.lazy = false;
      this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
   }
}
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
   return this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pcut,
         this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
}
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
      MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
   // 获取切面类型
   Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
   validate(candidateAspectClass);
   // 获取方法上的Advice和PointCut
   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 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);
   }

   // 设置切面的其他属性
   springAdvice.setAspectName(aspectName);
   springAdvice.setDeclarationOrder(declarationOrder);
   String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
   if (argNames != null) {
      springAdvice.setArgumentNamesFromStringArray(argNames);
   }
   springAdvice.calculateArgumentBindings();
   return springAdvice;
}

生成代理类

判断是否需要代理

  1. 进入初始化后置处理阶段

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
       if (bean != null) {
          Object cacheKey = getCacheKey(bean.getClass(), beanName);
          if (!this.earlyProxyReferences.contains(cacheKey)) {
             return wrapIfNecessary(bean, beanName, cacheKey);
          }
       }
       return bean;
    }
    
  2. 进入wrapIfNecessary

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    		if (beanName != null && 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;
    		}
    
    		// 匹配相关的拦截器
    		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;
    	}
    
  3. 直接进入核心处理方法canApply

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
   Assert.notNull(pc, "Pointcut must not be null");
   // 如果当前类与表达式中的类不匹配,则直接返回false
   if (!pc.getClassFilter().matches(targetClass)) {
      return false;
   }
   // 获取方法匹配器
   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<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
   classes.add(targetClass);
   for (Class<?> clazz : classes) {
      Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
      // 遍历所有的发方法,进行匹配,如果匹配通过,则返回true.
      for (Method method : methods) {
         if ((introductionAwareMethodMatcher != null &&
               introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
               methodMatcher.matches(method, targetClass)) {
            return true;
         }
      }
   }

   return false;
}

判断使用jdk还是cglib?

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

创建代理

public Object getProxy(ClassLoader classLoader) {
   if (logger.isDebugEnabled()) {
      logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
   }

   try {
      Class<?> rootClass = this.advised.getTargetClass();
      Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

      Class<?> proxySuperClass = rootClass;
      if (ClassUtils.isCglibProxyClass(rootClass)) {
         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...
      Enhancer enhancer = createEnhancer();
      if (classLoader != null) {
         enhancer.setClassLoader(classLoader);
         if (classLoader instanceof SmartClassLoader &&
               ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
            enhancer.setUseCache(false);
         }
      }
      enhancer.setSuperclass(proxySuperClass);
      enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
      enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
      enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

      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 ex) {
      throw new AopConfigException("Could not generate CGLIB subclass of class [" +
            this.advised.getTargetClass() + "]: " +
            "Common causes of this problem include using a final class or a non-visible class",
            ex);
   }
   catch (IllegalArgumentException ex) {
      throw new AopConfigException("Could not generate CGLIB subclass of class [" +
            this.advised.getTargetClass() + "]: " +
            "Common causes of this problem include using a final class or a non-visible class",
            ex);
   }
   catch (Exception ex) {
      // TargetSource.getTarget() failed
      throw new AopConfigException("Unexpected AOP exception", ex);
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值