spring的aop的源码解析

spring中最重要的概念有2个,一个是IOC(inverse of control)和aop(面向切面编程),今天我们来聊聊aop面向切面编程;

基础概念这里就不做介绍了,今天我们主要来说说aop的实现,先来一个简单的例子:

public interface Dao {

    public void insert();

    public void select();
}

public class DaoImpl implements Dao {
    @Override
    public void insert() {
        System.out.println("Enter DaoImpl.insert()");
    }

    @Override
    public void select() {
        System.out.println("Enter DaoImpl.select()");
    }
}
public class TimeHandler {

    public static void print(){
        System.out.println("CurrentTime:" + System.currentTimeMillis());
    }
}
<bean id="daoImpl" class="controller.DaoImpl" />
<bean id="timeHandler" class="controller.TimeHandler" />

<aop:config proxy-target-class="true">
    <aop:aspect id="time" ref="timeHandler">
        <aop:pointcut id="addAllMethod" expression="execution(* controller.Dao.*(..))" />
        <aop:before method="print" pointcut-ref="addAllMethod" />
        <aop:after method="print" pointcut-ref="addAllMethod" />
    </aop:aspect>
</aop:config>
public class Application {
    public static void main(String[] args) {
   /*     ConfigurableApplicationContext context =  SpringApplication.run(Application.class,args);
        Dao dao =(Dao) context.getBean("daoImpl");
        dao.insert();
        dao.select();*/
        ApplicationContext context = new ClassPathXmlApplicationContext("aop.xml");
        Dao dao =(Dao) context.getBean("daoImpl");
        dao.insert();
        dao.select();
    }
}

我们都知道aop的实现原理是jdk的动态代理(当实现接口的时候)和cglib代理,这2种技术都是通过代理对象来实现aop的,既然是通过代理对象,那么这个代理对象是什么时候生成的?答案就是bean初始化的时候,所以我们先从bean解析来看起:

BeanDefinitionDocumentReader

这是一个接口,他只有一个方法registerBeanDefinitions方法,这个方法的作用是从xml解析bean的配置文件并生成BeanDefinitions对象以便后面初始化bean的时候使用;

DefaultBeanDefinitionDocumentReader

这个是BeanDedfnitionDocumentReader类的唯一一个默认实现类;

@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
   this.readerContext = readerContext;
   logger.debug("Loading bean definitions");
   Element root = doc.getDocumentElement();
   doRegisterBeanDefinitions(root);
}
/**
 * Register each bean definition within the given root {@code <beans/>} element.
 */
protected void doRegisterBeanDefinitions(Element root) {
   // Any nested <beans> elements will cause recursion in this method. In
   // order to propagate and preserve <beans> default-* attributes correctly,
   // keep track of the current (parent) delegate, which may be null. Create
   // the new (child) delegate with a reference to the parent for fallback purposes,
   // then ultimately reset this.delegate back to its original (parent) reference.
   // this behavior emulates a stack of delegates without actually necessitating one.
   //这是一个BeanDifinition的解析器,解析工作就由他来做
   BeanDefinitionParserDelegate parent = this.delegate;
   this.delegate = createDelegate(getReaderContext(), root, parent);

  //是不是默认的命名空间,true,这里的root的namespace是http://www.springframework.org/schema/beans
   if (this.delegate.isDefaultNamespace(root)) {
      String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
      if (StringUtils.hasText(profileSpec)) {
         String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
               profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
         if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
            if (logger.isInfoEnabled()) {
               logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
                     "] not matching: " + getReaderContext().getResource());
            }
            return;
         }
      }
   }

   //空方法
   preProcessXml(root);
  //解析BeanDefinitions,这就是解析的入口方法
   parseBeanDefinitions(root, this.delegate);
   //空方法
   postProcessXml(root);

   this.delegate = parent;
}
/**
 * Parse the elements at the root level in the document:
 * "import", "alias", "bean".
 * @param root the DOM root element of the document
 */
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
   if (delegate.isDefaultNamespace(root)) {
      //获取root节点的所有子节点,这里是beans节点下的所有bean
      NodeList nl = root.getChildNodes();
     //迭代所有的bean,
      for (int i = 0; i < nl.getLength(); i++) {
         Node node = nl.item(i);
         if (node instanceof Element) {
            Element ele = (Element) node;
            if (delegate.isDefaultNamespace(ele)) {
           //判断bean是不是默认的namespace,像<bean id="daoImpl" class="controller.DaoImpl" />会走这个分支,解析成一个
            //beanDefinition
               parseDefaultElement(ele, delegate);
            }
            else {
           //判断bean是不是默认的namespace,像<aop:config proxy-target-class="true">会走这个分支,解析成一个
              //beanDefinition
               delegate.parseCustomElement(ele);
            }
         }
      }
   }
   else {
      delegate.parseCustomElement(root);
   }
}

先从正常的bean标签解析看起:

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
  //解析import标签
   if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
      importBeanDefinitionResource(ele);
   }
  //解析alias标签
   else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
      processAliasRegistration(ele);
   }
  //解析bean标签,这里走的是正常的解析bean标签
   else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
      processBeanDefinition(ele, delegate);
   }
  //解析beans标签
   else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
      // recurse
      doRegisterBeanDefinitions(ele);
   }
}

进入正常的解析bean标签的方法:processBeanDefinition

/**
 * Process the given bean element, parsing the bean definition
 * and registering it with the registry.
 */
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
  //BeanDefinitionHolder看以看成是一个BeanDefinition的包装类,我们进去parseBeanDefinitionElement看看
   BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
   if (bdHolder != null) {
      //修饰BeanDefinitionHolder
      bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
      try {
         // Register the final decorated instance.
         //注册生成的BeanDefinitionbean 进factory
         BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
      }
      catch (BeanDefinitionStoreException ex) {
         getReaderContext().error("Failed to register bean definition with name '" +
               bdHolder.getBeanName() + "'", ele, ex);
      }
      // Send registration event.
      //发送一个注册事件,至此一个完整的beanDefinition的解析、生产、注册就已经完成乐
      getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
   }
}
/**
 * Parses the supplied {@code <bean>} element. May return {@code null}
 * if there were errors during parse. Errors are reported to the
 * {@link org.springframework.beans.factory.parsing.ProblemReporter}.
 */
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
   return parseBeanDefinitionElement(ele, null);
}
/**
 * Parses the supplied {@code <bean>} element. May return {@code null}
 * if there were errors during parse. Errors are reported to the
 * {@link org.springframework.beans.factory.parsing.ProblemReporter}.
 */
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
  //获取bean的id,这里是timeHandler
   String id = ele.getAttribute(ID_ATTRIBUTE);
  //获取bean的name,这里是空值
   String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

   List<String> aliases = new ArrayList<String>();
   //如果name不为空值,那么split后放进list别名集合
   if (StringUtils.hasLength(nameAttr)) {
      String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
      aliases.addAll(Arrays.asList(nameArr));
   }

   String beanName = id;
  //如果id为空,但是name部位不为空,那么取name的第一个集合对象赋值给beanName
   if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
      beanName = aliases.remove(0);
      if (logger.isDebugEnabled()) {
         logger.debug("No XML 'id' specified - using '" + beanName +
               "' as bean name and " + aliases + " as aliases");
      }
   }

   //检查beanName是否唯一
   if (containingBean == null) {
      checkNameUniqueness(beanName, aliases, ele);
   }
  //生成BeanDefinition对象的方法
   AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
   if (beanDefinition != null) {
      if (!StringUtils.hasText(beanName)) {
         try {
            if (containingBean != null) {
               beanName = BeanDefinitionReaderUtils.generateBeanName(
                     beanDefinition, this.readerContext.getRegistry(), true);
            }
            else {
               beanName = this.readerContext.generateBeanName(beanDefinition);
               // Register an alias for the plain bean class name, if still possible,
               // if the generator returned the class name plus a suffix.
               // This is expected for Spring 1.2/2.0 backwards compatibility.
               String beanClassName = beanDefinition.getBeanClassName();
               if (beanClassName != null &&
                     beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
                     !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
                  aliases.add(beanClassName);
               }
            }
            if (logger.isDebugEnabled()) {
               logger.debug("Neither XML 'id' nor 'name' specified - " +
                     "using generated bean name [" + beanName + "]");
            }
         }
         catch (Exception ex) {
            error(ex.getMessage(), ele);
            return null;
         }
      }
      String[] aliasesArray = StringUtils.toStringArray(aliases);
     //返回BeanDefinitionHolder对象
      return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
   }

   return null;
}
/**
 * Parse the bean definition itself, without regard to name or aliases. May return
 * {@code null} if problems occurred during the parsing of the bean definition.
 */
public AbstractBeanDefinition parseBeanDefinitionElement(
      Element ele, String beanName, BeanDefinition containingBean) {

   this.parseState.push(new BeanEntry(beanName));

   //获取class标签对象
   String className = null;
   if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
      className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
   }

   try {
     //获取parent标签对象
      String parent = null;
      if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
         parent = ele.getAttribute(PARENT_ATTRIBUTE);
      }
    //生成BeanDefinition对象
      AbstractBeanDefinition bd = createBeanDefinition(className, parent);
      //设置beanDefinition的一般属性,比如scope,autowired等等
      parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);

      bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
    //解析元数据信息
      parseMetaElements(ele, bd);
    //解析bean的lookup-method标签
      parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
    //解析bean的replaced-method标签
      parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
    //解析bean的constructor-arg标签
      parseConstructorArgElements(ele, bd);
     //解析property标签
      parsePropertyElements(ele, bd);
     //解析qualifier标签
      parseQualifierElements(ele, bd);

      bd.setResource(this.readerContext.getResource());
      bd.setSource(extractSource(ele));

      return bd;
   }
   catch (ClassNotFoundException ex) {
      error("Bean class [" + className + "] not found", ele, ex);
   }
   catch (NoClassDefFoundError err) {
      error("Class that bean class [" + className + "] depends on not found", ele, err);
   }
   catch (Throwable ex) {
      error("Unexpected failure during bean definition parsing", ele, ex);
   }
   finally {
      this.parseState.pop();
   }

   return null;
}
/**
 * Create a bean definition for the given class name and parent name.
 * @param className the name of the bean class
 * @param parentName the name of the bean's parent bean
 * @return the newly created bean definition
 * @throws ClassNotFoundException if bean class resolution was attempted but failed
 */
protected AbstractBeanDefinition createBeanDefinition(String className, String parentName)
      throws ClassNotFoundException {

   return BeanDefinitionReaderUtils.createBeanDefinition(
         parentName, className, this.readerContext.getBeanClassLoader());
}
/**
 * Create a new GenericBeanDefinition for the given parent name and class name,
 * eagerly loading the bean class if a ClassLoader has been specified.
 * @param parentName the name of the parent bean, if any
 * @param className the name of the bean class, if any
 * @param classLoader the ClassLoader to use for loading bean classes
 * (can be {@code null} to just register bean classes by name)
 * @return the bean definition
 * @throws ClassNotFoundException if the bean class could not be loaded
 */
public static AbstractBeanDefinition createBeanDefinition(
      String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException {

  //一般的Bean生成的都是 GenericBeanDefinition 对象
  GenericBeanDefinition bd = new GenericBeanDefinition();
 //设置parentName
   bd.setParentName(parentName);
   if (className != null) {
     //设置BeanClass的Class对象
      if (classLoader != null) {
         bd.setBeanClass(ClassUtils.forName(className, classLoader));
      }
      else {
         bd.setBeanClassName(className);
      }
   }
   return bd;
}

以上是正常的bean的解析流程,对于spingaop的标签<aop:config />走的是另一套方法分支parseCustomElement

public BeanDefinition parseCustomElement(Element ele) {
   return parseCustomElement(ele, null);
}

public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
  //获取aop的namespaceURI,这里是http://www.springframework.org/schema/aop
   String namespaceUri = getNamespaceURI(ele);
  //通过namespaceuri获取NamespaceHandler为AopNamespaceHandler 
   NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
   if (handler == null) {
      error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
      return null;
   }
  //通过NamespaceHandler解析aop:config标签
   return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
/**
 * Parses the supplied {@link Element} by delegating to the {@link BeanDefinitionParser} that is
 * registered for that {@link Element}.
 */
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
   //调用ConfigBeanDefinitionParser的parse方法
   return findParserForElement(element, parserContext).parse(element, parserContext);
}

/**
 * Locates the {@link BeanDefinitionParser} from the register implementations using
 * the local name of the supplied {@link Element}.
 */
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
  //这里的localName=config
   String localName = parserContext.getDelegate().getLocalName(element);
   //通过localName获得Parse对象ConfigBeanDefinitionParser
   BeanDefinitionParser parser = this.parsers.get(localName);
   if (parser == null) {
      parserContext.getReaderContext().fatal(
            "Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
   }
   return parser;
}

ConfigBeanDefinitionParser

@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
   CompositeComponentDefinition compositeDef =
         new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
   parserContext.pushContainingComponent(compositeDef);
   //创建自动代理对象的BeanDefinition,AspectJAwareAdvisorAutoProxyCreator和internalAutoProxyCreator
   configureAutoProxyCreator(parserContext, element);
  //解析aop:config标签
   List<Element> childElts = DomUtils.getChildElements(element);
   for (Element elt: childElts) {
     //先解析aspect标签
      String localName = parserContext.getDelegate().getLocalName(elt);
      if (POINTCUT.equals(localName)) {
         parsePointcut(elt, parserContext);
      }
      else if (ADVISOR.equals(localName)) {
         parseAdvisor(elt, parserContext);
      }
      //进入aspect标签解析
      else if (ASPECT.equals(localName)) {
         parseAspect(elt, parserContext);
      }
   }

   parserContext.popAndRegisterContainingComponent();
   return null;
}

开始解析aspect标签:

private void parseAspect(Element aspectElement, ParserContext parserContext) {
  //aspect的id标签
   String aspectId = aspectElement.getAttribute(ID);
  //ref标签
   String aspectName = aspectElement.getAttribute(REF);

   try {
      this.parseState.push(new AspectEntry(aspectId, aspectName));
      List<BeanDefinition> beanDefinitions = new ArrayList<BeanDefinition>();
      List<BeanReference> beanReferences = new ArrayList<BeanReference>();

      List<Element> declareParents = DomUtils.getChildElementsByTagName(aspectElement, DECLARE_PARENTS);
      for (int i = METHOD_INDEX; i < declareParents.size(); i++) {
         Element declareParentsElement = declareParents.get(i);
         beanDefinitions.add(parseDeclareParents(declareParentsElement, parserContext));
      }

      // We have to parse "advice" and all the advice kinds in one loop, to get the
      // ordering semantics right.
      //迭代aspect标签的所有子标签
      NodeList nodeList = aspectElement.getChildNodes();
      boolean adviceFoundAlready = false;
      for (int i = 0; i < nodeList.getLength(); i++) {
         Node node = nodeList.item(i);
         //判断是不是一个通知
         if (isAdviceNode(node, parserContext)) {
            if (!adviceFoundAlready) {
               adviceFoundAlready = true;
               if (!StringUtils.hasText(aspectName)) {
                  parserContext.getReaderContext().error(
                        "<aspect> tag needs aspect bean reference via 'ref' attribute when declaring advices.",
                        aspectElement, this.parseState.snapshot());
                  return;
               }
               beanReferences.add(new RuntimeBeanReference(aspectName));
            }
           //主要看这个解析advice的方法
            AbstractBeanDefinition advisorDefinition = parseAdvice(
                  aspectName, i, aspectElement, (Element) node, parserContext, beanDefinitions, beanReferences);
            beanDefinitions.add(advisorDefinition);
         }
      }

      AspectComponentDefinition aspectComponentDefinition = createAspectComponentDefinition(
            aspectElement, aspectId, beanDefinitions, beanReferences, parserContext);
      parserContext.pushContainingComponent(aspectComponentDefinition);

      List<Element> pointcuts = DomUtils.getChildElementsByTagName(aspectElement, POINTCUT);
      for (Element pointcutElement : pointcuts) {
       //解析pointcut标签
         parsePointcut(pointcutElement, parserContext);
      }

      parserContext.popAndRegisterContainingComponent();
   }
   finally {
      this.parseState.pop();
   }
}
判断是不是一个通知:主要有前置通知,后置通知,环绕通知,异常通知,返回通知五种类型
/**
 * Return {@code true} if the supplied node describes an advice type. May be one of:
 * '{@code before}', '{@code after}', '{@code after-returning}',
 * '{@code after-throwing}' or '{@code around}'.
 */
private boolean isAdviceNode(Node aNode, ParserContext parserContext) {
   if (!(aNode instanceof Element)) {
      return false;
   }
   else {
      String name = parserContext.getDelegate().getLocalName(aNode);
      return (BEFORE.equals(name) || AFTER.equals(name) || AFTER_RETURNING_ELEMENT.equals(name) ||
            AFTER_THROWING_ELEMENT.equals(name) || AROUND.equals(name));
   }
}
/**
 * Parses one of '{@code before}', '{@code after}', '{@code after-returning}',
 * '{@code after-throwing}' or '{@code around}' and registers the resulting
 * BeanDefinition with the supplied BeanDefinitionRegistry.
 * @return the generated advice RootBeanDefinition
 */
private AbstractBeanDefinition parseAdvice(
      String aspectName, int order, Element aspectElement, Element adviceElement, ParserContext parserContext,
      List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) {

   try {
      this.parseState.push(new AdviceEntry(parserContext.getDelegate().getLocalName(adviceElement)));

      // create the method factory bean
    //创建一个方法工厂的bean,targetBeanName = TimeHandler,methodName = print
      RootBeanDefinition methodDefinition = new RootBeanDefinition(MethodLocatingFactoryBean.class);
      methodDefinition.getPropertyValues().add("targetBeanName", aspectName);
      methodDefinition.getPropertyValues().add("methodName", adviceElement.getAttribute("method"));
      methodDefinition.setSynthetic(true);

      // create instance factory definition
    //创建一个实例工厂的bean
      RootBeanDefinition aspectFactoryDef =
            new RootBeanDefinition(SimpleBeanFactoryAwareAspectInstanceFactory.class);
      aspectFactoryDef.getPropertyValues().add("aspectBeanName", aspectName);
      aspectFactoryDef.setSynthetic(true);

      // register the pointcut
       //注册一个pointcut的BeanDefinition
      AbstractBeanDefinition adviceDef = createAdviceDefinition(
            adviceElement, parserContext, aspectName, order, methodDefinition, aspectFactoryDef,
            beanDefinitions, beanReferences);

      // configure the advisor
      RootBeanDefinition advisorDefinition = new RootBeanDefinition(AspectJPointcutAdvisor.class);
      advisorDefinition.setSource(parserContext.extractSource(adviceElement));
      advisorDefinition.getConstructorArgumentValues().addGenericArgumentValue(adviceDef);
      if (aspectElement.hasAttribute(ORDER_PROPERTY)) {
         advisorDefinition.getPropertyValues().add(
               ORDER_PROPERTY, aspectElement.getAttribute(ORDER_PROPERTY));
      }

      // register the final advisor
      //注册完整的advisor,包含切点和切面
      parserContext.getReaderContext().registerWithGeneratedName(advisorDefinition);

      return advisorDefinition;
   }
   finally {
      this.parseState.pop();
   }
}
/**
 * Creates the RootBeanDefinition for a POJO advice bean. Also causes pointcut
 * parsing to occur so that the pointcut may be associate with the advice bean.
 * This same pointcut is also configured as the pointcut for the enclosing
 * Advisor definition using the supplied MutablePropertyValues.
 */
private AbstractBeanDefinition createAdviceDefinition(
      Element adviceElement, ParserContext parserContext, String aspectName, int order,
      RootBeanDefinition methodDef, RootBeanDefinition aspectFactoryDef,
      List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) {

   //解析before标签,返回一个AspectJMethodBeforeAdvice的RootBeanDefinition
   RootBeanDefinition adviceDefinition = new RootBeanDefinition(getAdviceClass(adviceElement, parserContext));
   adviceDefinition.setSource(parserContext.extractSource(adviceElement));
  //配置通知类,这里是timeHandler
   adviceDefinition.getPropertyValues().add(ASPECT_NAME_PROPERTY, aspectName);
  //配置通知的方法,这里是print
   adviceDefinition.getPropertyValues().add(DECLARATION_ORDER_PROPERTY, order);

   if (adviceElement.hasAttribute(RETURNING)) {
      adviceDefinition.getPropertyValues().add(
            RETURNING_PROPERTY, adviceElement.getAttribute(RETURNING));
   }
   if (adviceElement.hasAttribute(THROWING)) {
      adviceDefinition.getPropertyValues().add(
            THROWING_PROPERTY, adviceElement.getAttribute(THROWING));
   }
   if (adviceElement.hasAttribute(ARG_NAMES)) {
      adviceDefinition.getPropertyValues().add(
            ARG_NAMES_PROPERTY, adviceElement.getAttribute(ARG_NAMES));
   }

   ConstructorArgumentValues cav = adviceDefinition.getConstructorArgumentValues();
   cav.addIndexedArgumentValue(METHOD_INDEX, methodDef);

   Object pointcut = parsePointcutProperty(adviceElement, parserContext);
   if (pointcut instanceof BeanDefinition) {
      cav.addIndexedArgumentValue(POINTCUT_INDEX, pointcut);
      beanDefinitions.add((BeanDefinition) pointcut);
   }
//解析pointcut的索引,这里是addAllMethod
   else if (pointcut instanceof String) {
      RuntimeBeanReference pointcutRef = new RuntimeBeanReference((String) pointcut);
      cav.addIndexedArgumentValue(POINTCUT_INDEX, pointcutRef);
      beanReferences.add(pointcutRef);
   }

   cav.addIndexedArgumentValue(ASPECT_INSTANCE_FACTORY_INDEX, aspectFactoryDef);
 //返回的就是一个完整的切面的bizdefine,包含切点的索引和切面
   return adviceDefinition;
}
/**
 * Parses the supplied {@code <pointcut>} and registers the resulting
 * Pointcut with the BeanDefinitionRegistry.
 */
private AbstractBeanDefinition parsePointcut(Element pointcutElement, ParserContext parserContext) {
   String id = pointcutElement.getAttribute(ID);
   String expression = pointcutElement.getAttribute(EXPRESSION);

   AbstractBeanDefinition pointcutDefinition = null;

   try {
      this.parseState.push(new PointcutEntry(id));
      pointcutDefinition = createPointcutDefinition(expression);
      pointcutDefinition.setSource(parserContext.extractSource(pointcutElement));

      String pointcutBeanName = id;
      if (StringUtils.hasText(pointcutBeanName)) {
         parserContext.getRegistry().registerBeanDefinition(pointcutBeanName, pointcutDefinition);
      }
      else {
         pointcutBeanName = parserContext.getReaderContext().registerWithGeneratedName(pointcutDefinition);
      }

      parserContext.registerComponent(
            new PointcutComponentDefinition(pointcutBeanName, pointcutDefinition, expression));
   }
   finally {
      this.parseState.pop();
   }

   return pointcutDefinition;
}

整个解析到这就结束了!

猜你喜欢

转载自blog.csdn.net/chengkui1990/article/details/81223547