• spring AOP XML解析


    <aop:config>  标签的解析:
    
        <bean id="loggingAspect" class="com.zhuguang.jack.aop.aspect.AspectXml1"></bean>
        <aop:config>
            <aop:pointcut id="pointcut" expression="execution(* com.zhuguang.jack.aop.aspect.AspectXml1.*(..))" />
            <aop:aspect  ref="loggingAspect" order="1" >
                <aop:before method="before" pointcut-ref="pointcut"/>
                <aop:after method="after" pointcut-ref="pointcut"/>
                <aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>
                <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="exception"/>
            </aop:aspect>
        </aop:config>
    aop:config对应的类是AspectJAwareAdvisorAutoProxyCreator。加到bean工厂。
    aop:aspect  不用解析成类。
    aop:before 对应的类是AspectJPointcutAdvisor,里面有AspectJMethodBeforeAdvice,里面有MethodLocatingFactoryBean和SimpleBeanFactoryAwareAspectInstanceFactory和pointcut。加到bean工厂。
    aop:after ,aop:after-returning,aop:after-throwing与aop:before类似。
    
    类的属性值就是根据标签上面写的解析出来的。
    解析自定义标签就是创建bean的定义,<aop:before,<aop:after,<aop:after-returning,<aop:after-throwing。分别对应AspectJMethodBeforeAdvice.class;AspectJAfterAdvice.class;AspectJAfterReturningAdvice.class;AspectJAfterThrowingAdvice.class;AspectJAroundAdvice.class;  
     AspectJAwareAdvisorAutoProxyCreator是支持AOP功能的入口类,必定实现BeanPostProcessor接口,bean实例化的时候就回去调用这个类,就会找这个类有没有切面,有切面就生成代理,
    首先找到AopNamespaceHandler,然后找到registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
    
    public class AopNamespaceHandler extends NamespaceHandlerSupport {
        @Override
        public void init() {
            registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
            registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
            registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
            registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
        }
    }
    ConfigBeanDefinitionParser类里面有一个解析标签的方法parse(),
    
    public BeanDefinition parse(Element element, ParserContext parserContext) { //element = [aop:config: null],parserContext = org.springframework.beans.factory.xml.ParserContext@2fd953a6,
            CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
            parserContext.pushContainingComponent(compositeDef);
    
            configureAutoProxyCreator(parserContext, element);  //ParserContext里面有一个属性XmlReaderContext readerContext,BeanDefinitionParserDelegate delegate,解析这个元素就是为了创建BeanDefinition对象,创建AspectJAwareAdvisorAutoProxyCreator的bean定义并且加载到bean工厂。这个类实现了BeanPostProcessor接口,实例化任何一个bean的时候,会调用spring容器中所有BeanPostProcessor接口的类的方法,AspectJAwareAdvisorAutoProxyCreator就会去检测要实例化的这个bean有没有切面,有切面,就帮这个bean生成代理,
    
            List<Element> childElts = DomUtils.getChildElements(element);   //[[aop:pointcut], [aop:advisor]]子标签,
            for (Element elt: childElts) {
                String localName = parserContext.getDelegate().getLocalName(elt);   //aop下面就3个标签,
                if (POINTCUT.equals(localName)) {
                    parsePointcut(elt, parserContext);
                }
                else if (ADVISOR.equals(localName)) {
                    parseAdvisor(elt, parserContext);
                }
                else if (ASPECT.equals(localName)) {
                    parseAspect(elt, parserContext);
                }
            }
    
            parserContext.popAndRegisterContainingComponent();
            return null;
        }
    private void configureAutoProxyCreator(ParserContext parserContext, Element element) {
            AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);
        }
    
    public static void registerAspectJAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
            BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary(
                    parserContext.getRegistry(), parserContext.extractSource(sourceElement));  //创建beanDefinition 对象,返回AspectJAwareAdvisorAutoProxyCreator的bean的定义,
            useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
            registerComponentIfNecessary(beanDefinition, parserContext);
        }
    
    public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
            return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source);   //注册器是DefaultListableBeanFactory,null,
        }
    private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {  //AspectJAwareAdvisorAutoProxyCreator,bean工厂,null,
            Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
            if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {   //看bean工厂中有没有AspectJAwareAdvisorAutoProxyCreator的实例,名字是internalAutoProxyCreator,有就直接返回,没有就在bean工厂创建AspectJAwareAdvisorAutoProxyCreator的实例,名字叫做internalAutoProxyCreator。
                BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
                if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
                    int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
                    int requiredPriority = findPriorityForClass(cls);
                    if (currentPriority < requiredPriority) {
                        apcDefinition.setBeanClassName(cls.getName());
                    }
                }
                return null;
            }
            RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);  //创建AspectJAwareAdvisorAutoProxyCreator的实例
            beanDefinition.setSource(source);
            beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
            beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);   //加到bean工厂,名字叫做internalAutoProxyCreator,
            return beanDefinition;
        }
    private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
            if (sourceElement != null) {
                boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));  //获取[aop:config]标签的proxy-target-class="false"属性,true就是cglib的动态代理,faslse就是jdk的动态代理,没有写就是jdk的动态代理,
                if (proxyTargetClass) {//true
                    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                }
                boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));   //sourceElement = [aop:config]标签,
                if (exposeProxy) {
                    AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
                }
            }
        }
    public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
            if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
                BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
                definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);   //往internalAutoProxyCreator的bean定义里面加了一个属性,
            }
        }
    private static void registerComponentIfNecessary(BeanDefinition beanDefinition, ParserContext parserContext) {  //AspectJAwareAdvisorAutoProxyCreator的bean定义,org.springframework.beans.factory.xml.ParserContext@2fd953a6,
            if (beanDefinition != null) {
                BeanComponentDefinition componentDefinition = new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);  //把AspectJAwareAdvisorAutoProxyCreator的bean定义包装成BeanComponentDefinition,包装的名称叫做internalAutoProxyCreator,
                parserContext.registerComponent(componentDefinition);
            }
        }
    BeanComponentDefinition extends BeanDefinitionHolder。
    BeanDefinition最终会包装成BeanDefinitionHolder,BeanDefinitionHolder有BeanDefinition beanDefinition是bean的定义和String beanName 是bean的名称。
    private void parseAspect(Element aspectElement, ParserContext parserContext) {  //解析<aop:aspect标签,
            String aspectId = aspectElement.getAttribute(ID);   //id属性,
            String aspectName = aspectElement.getAttribute(REF);   //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));
                }
    
                NodeList nodeList = aspectElement.getChildNodes();//aspect的子元素,<aop:before,<aop:after,<aop:after-returning,<aop:after-throwing。
                boolean adviceFoundAlready = false;
                for (int i = 0; i < nodeList.getLength(); i++) {
                    Node node = nodeList.item(i);   //<aop:before,<aop:after,<aop:after-returning,<aop:after-throwing。
                    if (isAdviceNode(node, parserContext)) {
                        if (!adviceFoundAlready) {
                            adviceFoundAlready = true;
                            beanReferences.add(new RuntimeBeanReference(aspectName));
                        }
    
                        AbstractBeanDefinition advisorDefinition = parseAdvice(aspectName, i, aspectElement, (Element) node, parserContext, beanDefinitions, beanReferences);  //解析通知节点<aop:before,<aop:after,<aop:after-returning,<aop:after-throwing标签。目的也是为了创建BeanDefinition。
    //返回AspectJPointcutAdvisor的bean定义,constructorArgumentValues属性里面的gebericArgumentValues里面有AspectJMethodBeforeAdvice(现在解析的是aop:before标签)(还有after,around,throw,exception几种)的bean定义里面的constructorArgumentValues属性里面有MethodLocatingFactoryBean的bean定义和SimpleBeanFactoryAwareAspectInstanceFactory的bean定义和pointcut。
    
                        beanDefinitions.add(advisorDefinition);//4种前置后置环绕等通知加进去,一个是before标签的bean定义,一个是after的bean定义,一个是afterReturn的bean定义,一个是afterThrow的bean定义。
                    }
                }
    //解析aop:aspect标签,就是把里面的aop:before,aop:after,aop:afterthrow,aop:afterRuturnning,这几种标签解析成bean的定义,跟需要加入切面的类还没有建立直接的关系。
    
                AspectComponentDefinition aspectComponentDefinition = createAspectComponentDefinition(
                        aspectElement, aspectId, beanDefinitions, beanReferences, parserContext);
                parserContext.pushContainingComponent(aspectComponentDefinition);
    
                List<Element> pointcuts = DomUtils.getChildElementsByTagName(aspectElement, POINTCUT);  //这个<aop:aspect  标签里面的pointcut标签,
                for (Element pointcutElement : pointcuts) {
                    parsePointcut(pointcutElement, parserContext);
                }
    
                parserContext.popAndRegisterContainingComponent();
            }
            finally {
                this.parseState.pop();
            }
        }
    private AbstractBeanDefinition parseAdvice(String aspectName, int order, Element aspectElement, Element adviceElement, ParserContext parserContext,List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) {//aspectName = aop:aspect标签的ref属性的值,aspectElement = [aop:aspect: null]标签,adviceElement = <aop:before,<aop:after,<aop:after-returning,<aop:after-throwing。
    
            try {
                this.parseState.push(new AdviceEntry(parserContext.getDelegate().getLocalName(adviceElement)));
    
                RootBeanDefinition methodDefinition = new RootBeanDefinition(MethodLocatingFactoryBean.class);   //创建这个的bean定义,
                methodDefinition.getPropertyValues().add("targetBeanName", aspectName);//loggingAspect,切面类名称。
                methodDefinition.getPropertyValues().add("methodName", adviceElement.getAttribute("method"));  //执行的方法,
                methodDefinition.setSynthetic(true);
    
                RootBeanDefinition aspectFactoryDef = new RootBeanDefinition(SimpleBeanFactoryAwareAspectInstanceFactory.class); //创建这个的bean定义,
                aspectFactoryDef.getPropertyValues().add("aspectBeanName", aspectName);//loggingAspect,切面类名称。
                aspectFactoryDef.setSynthetic(true);
    
                AbstractBeanDefinition adviceDef = createAdviceDefinition(adviceElement, parserContext, aspectName, order, methodDefinition, aspectFactoryDef,beanDefinitions, beanReferences);  //返回AspectJMethodBeforeAdvice的bean定义constructorArgumentValues属性里面有MethodLocatingFactoryBean的bean定义和SimpleBeanFactoryAwareAspectInstanceFactory的bean定义和pointcut,前置通知的beanDefinition(<aop:before>标签的beanDefinition)。
    
                // configure the advisor
                RootBeanDefinition advisorDefinition = new RootBeanDefinition(AspectJPointcutAdvisor.class);  //切面内
                advisorDefinition.setSource(parserContext.extractSource(adviceElement));   //[aop:before: null],
                advisorDefinition.getConstructorArgumentValues().addGenericArgumentValue(adviceDef);  //切面里面必须要有advice,通过构造函数设置值。
                if (aspectElement.hasAttribute(ORDER_PROPERTY)) {
                    advisorDefinition.getPropertyValues().add(ORDER_PROPERTY, aspectElement.getAttribute(ORDER_PROPERTY));
                }
    
                // register the final advisor
                parserContext.getReaderContext().registerWithGeneratedName(advisorDefinition);
    
                return advisorDefinition;//返回这个切面。AspectJPointcutAdvisor的bean定义,constructorArgumentValues属性里面的gebericArgumentValues属性里面有AspectJMethodBeforeAdvice的bean定义里面的constructorArgumentValues属性里面有MethodLocatingFactoryBean的bean定义和SimpleBeanFactoryAwareAspectInstanceFactory的bean定义和pointcut。
            }
            finally {
                this.parseState.pop();
            }
        }
    private AbstractBeanDefinition createAdviceDefinition(
                Element adviceElement, ParserContext parserContext, String aspectName, int order,
                RootBeanDefinition methodDef, RootBeanDefinition aspectFactoryDef,
                List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) {
    
            RootBeanDefinition adviceDefinition = new RootBeanDefinition(getAdviceClass(adviceElement, parserContext));   //AspectJMethodBeforeAdvice的bean定义,before的类是AspectJMethodBeforeAdvice,after的类是AspectJAfterAdvice,return的类是AspectJAfterReturningAdvice,afterThrowing的类是AspectJAfterThrowingAdvice,around的类是AspectJAroundAdvice。
            adviceDefinition.setSource(parserContext.extractSource(adviceElement));
    
            adviceDefinition.getPropertyValues().add(ASPECT_NAME_PROPERTY, aspectName);  //切面类名称
            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);  //解析pointcut,
            if (pointcut instanceof BeanDefinition) {//有pointcut属性,返回bean定义,
                cav.addIndexedArgumentValue(POINTCUT_INDEX, pointcut);
                beanDefinitions.add((BeanDefinition) pointcut);
            }
            else if (pointcut instanceof String) {//有pointcut-ref属性,返回字符串,
                RuntimeBeanReference pointcutRef = new RuntimeBeanReference((String) pointcut);
                cav.addIndexedArgumentValue(POINTCUT_INDEX, pointcutRef);
                beanReferences.add(pointcutRef);
            }
    
            cav.addIndexedArgumentValue(ASPECT_INSTANCE_FACTORY_INDEX, aspectFactoryDef);
    
            return adviceDefinition;  //返回AspectJMethodBeforeAdvice的bean定义里面有MethodLocatingFactoryBean的bean定义和SimpleBeanFactoryAwareAspectInstanceFactory的bean定义和pointcut。
        }
    private Class<?> getAdviceClass(Element adviceElement, ParserContext parserContext) {
            String elementName = parserContext.getDelegate().getLocalName(adviceElement);
            if (BEFORE.equals(elementName)) {//前置通知
                return AspectJMethodBeforeAdvice.class;
            }
            else if (AFTER.equals(elementName)) {//后置通知
                return AspectJAfterAdvice.class;
            }
            else if (AFTER_RETURNING_ELEMENT.equals(elementName)) {//返回通知
                return AspectJAfterReturningAdvice.class;
            }
            else if (AFTER_THROWING_ELEMENT.equals(elementName)) {//异常通知
                return AspectJAfterThrowingAdvice.class;
            }
            else if (AROUND.equals(elementName)) {//环绕通知
                return AspectJAroundAdvice.class;
            }
        }
    private Object parsePointcutProperty(Element element, ParserContext parserContext) {  //element = aop:before标签,
            if (element.hasAttribute(POINTCUT) && element.hasAttribute(POINTCUT_REF)) {   //没有pointcut和pointcut-ref属性,直接报错。
                parserContext.getReaderContext().error("Cannot define both 'pointcut' and );
                return null;
            }
            else if (element.hasAttribute(POINTCUT)) {
                String expression = element.getAttribute(POINTCUT);
                AbstractBeanDefinition pointcutDefinition = createPointcutDefinition(expression);   //创建AspectJExpressionPointcut的bean定义,
                pointcutDefinition.setSource(parserContext.extractSource(element));
                return pointcutDefinition;
            }
            else if (element.hasAttribute(POINTCUT_REF)) {
                String pointcutRef = element.getAttribute(POINTCUT_REF);
                return pointcutRef;//返回字符串,
            }
        }
    private AspectComponentDefinition createAspectComponentDefinition(
                Element aspectElement, String aspectId, List<BeanDefinition> beanDefs,
                List<BeanReference> beanRefs, ParserContext parserContext) {
    
            BeanDefinition[] beanDefArray = beanDefs.toArray(new BeanDefinition[beanDefs.size()]);   //4个前置后置环绕等通知的数组,
            BeanReference[] beanRefArray = beanRefs.toArray(new BeanReference[beanRefs.size()]);
            Object source = parserContext.extractSource(aspectElement);
            return new AspectComponentDefinition(aspectId, beanDefArray, beanRefArray, source);
        }
    自定义标签都会有一个类与之对应,这个类是spring自己的类,然后加到spring的容器中,跟非自定义标签<bean>的解析类似。
    <aop:config>
            <aop:pointcut id="pointcut" expression="execution(* com.zhuguang.jack.aop.aspect.AspectXml1.*(..))" />
    aop:pointcut 解析成AspectJExpressionPointcut类,aop:config不用解析。
    
    类的属性值就是根据标签上面写的解析出来的。
    parsePointcut(elt, parserContext);   //[aop:pointcut: null],解析pointcut标签,
    
    private AbstractBeanDefinition parsePointcut(Element pointcutElement, ParserContext parserContext) {
            String id = pointcutElement.getAttribute(ID);   //pointcut
            String expression = pointcutElement.getAttribute(EXPRESSION);   //execution(* com.zhuguang.jack.aop.aspect.AspectXml1.*(..)),
            AbstractBeanDefinition pointcutDefinition = null;
            try {
                this.parseState.push(new PointcutEntry(id));
                pointcutDefinition = createPointcutDefinition(expression); //AspectJExpressionPointcut的bean定义,里面有point的表达式,
                pointcutDefinition.setSource(parserContext.extractSource(pointcutElement));
    
                String pointcutBeanName = id;  //pointcut
                if (StringUtils.hasText(pointcutBeanName)) {
                    parserContext.getRegistry().registerBeanDefinition(pointcutBeanName, pointcutDefinition);   //加到spring的容器,名字是pointcut,bean定义是AspectJExpressionPointcut的bean定义,
                }
    
                parserContext.registerComponent(new PointcutComponentDefinition(pointcutBeanName, pointcutDefinition, expression));  //pointcut,AspectJExpressionPointcut的beanDefinition,execution(* com.zhuguang.jack.aop.aspect.AspectXml1.*(..)),加到栈中,
            }
            finally {
                this.parseState.pop();
            }
    
            return pointcutDefinition;    //返回AspectJExpressionPointcut的bean定义,
        }
    protected AbstractBeanDefinition createPointcutDefinition(String expression) {
            RootBeanDefinition beanDefinition = new RootBeanDefinition(AspectJExpressionPointcut.class);
            beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
            beanDefinition.setSynthetic(true);
            beanDefinition.getPropertyValues().add(EXPRESSION, expression);
            return beanDefinition;
        }
    <aop:config proxy-target-class="false">
            <aop:advisor pointcut-ref="pc" advice-ref="userTxAdvice"/>
        </aop:config>
    aop:advisor 对应的类是DefaultBeanFactoryPointcutAdvisor,aop:config不用解析,然后解析pointcut-ref属性和 advice-ref属性。最后加到bean容器中去。
    
    类的属性值就是根据标签上面写的解析出来的。
    private void parseAdvisor(Element advisorElement, ParserContext parserContext) {     //解析Advisor标签
            AbstractBeanDefinition advisorDef = createAdvisorBeanDefinition(advisorElement, parserContext);   //创建bean定义对象,返回DefaultBeanFactoryPointcutAdvisor的beanDefinition,他的PropertyValues属性 = new RuntimeBeanNameReference(userTxAdvice),userTxAdvice是需要IOC依赖注入的,
            String id = advisorElement.getAttribute(ID);
    
            try {
                this.parseState.push(new AdvisorEntry(id));
                String advisorBeanName = id;
                if (StringUtils.hasText(advisorBeanName)) {
                    parserContext.getRegistry().registerBeanDefinition(advisorBeanName, advisorDef);   //advisorDef 加到bean工厂中去,
                }
                else {
                    advisorBeanName = parserContext.getReaderContext().registerWithGeneratedName(advisorDef);   //自动生成的名字org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0,advisorDef 加到bean工厂中去,
                }
    
                Object pointcut = parsePointcutProperty(advisorElement, parserContext);   //解析pointcut-ref属性,
                if (pointcut instanceof BeanDefinition) {//根据pointcut返回beanDefinition,根据pointcut-ref返回String,
                    advisorDef.getPropertyValues().add(POINTCUT, pointcut);  //  添加pointcut属性,
                    parserContext.registerComponent(new AdvisorComponentDefinition(advisorBeanName, advisorDef, (BeanDefinition) pointcut));//注册到栈中,
                }
                else if (pointcut instanceof String) {
                    advisorDef.getPropertyValues().add(POINTCUT, new RuntimeBeanReference((String) pointcut));//将pointcut-ref转换成RuntimeBeanReference,然后添加pointcut属性,
                    parserContext.registerComponent(new AdvisorComponentDefinition(advisorBeanName, advisorDef));//注册到栈中,
                }
            }
        }
    private AbstractBeanDefinition createAdvisorBeanDefinition(Element advisorElement, ParserContext parserContext) {  //[aop:advisor: null]标签,
            RootBeanDefinition advisorDefinition = new RootBeanDefinition(DefaultBeanFactoryPointcutAdvisor.class);
            advisorDefinition.setSource(parserContext.extractSource(advisorElement));
    
            String adviceRef = advisorElement.getAttribute(ADVICE_REF);   //advice-ref属性 = userTxAdvice(ref就是引用,就需要依赖注入)
            if (!StringUtils.hasText(adviceRef)) {
                parserContext.getReaderContext().error(pshot());
            }
            else {
                advisorDefinition.getPropertyValues().add(ADVICE_BEAN_NAME, new RuntimeBeanNameReference(adviceRef));   //userTxAdvice封装成RuntimeBeanNameReference,ref是引用要依赖注入,当发现依赖注入的类型是RuntimeBeanNameReference的时候,那么就会去通过bean工厂去拿这个对象。
            }
    
            if (advisorElement.hasAttribute(ORDER_PROPERTY)) {  //排序属性
                advisorDefinition.getPropertyValues().add(
                        ORDER_PROPERTY, advisorElement.getAttribute(ORDER_PROPERTY));
            }
    
            return advisorDefinition;//返回DefaultBeanFactoryPointcutAdvisor的beanDefinition,他的PropertyValues属性 = new RuntimeBeanNameReference(userTxAdvice),userTxAdvice是需要IOC依赖注入的,
        }
    private Object parsePointcutProperty(Element element, ParserContext parserContext) {  //element = [aop:advisor: null]标签,
            if (element.hasAttribute(POINTCUT) && element.hasAttribute(POINTCUT_REF)) {  //是否有pointcut属性
                parserContext.getReaderContext().error(ot());
                return null;
            }
            else if (element.hasAttribute(POINTCUT)) {   //pointcut属性
                // Create a pointcut for the anonymous pc and register it.
                String expression = element.getAttribute(POINTCUT);
                AbstractBeanDefinition pointcutDefinition = createPointcutDefinition(expression);  //AspectJExpressionPointcut的bean定义,
                pointcutDefinition.setSource(parserContext.extractSource(element));
                return pointcutDefinition;
            }
            else if (element.hasAttribute(POINTCUT_REF)) {  //pointcut-ref属性
                String pointcutRef = element.getAttribute(POINTCUT_REF);  //string:引用的名字,
                if (!StringUtils.hasText(pointcutRef)) {
                    parserContext.getReaderContext().error(ement, this.parseState.snapshot());
                    return null;
                }
                return pointcutRef; //string:引用的名字,
            }
        }
  • 相关阅读:
    Prototype.doc in Netsuite
    中文编码问题(utf8转为中文)
    js 取得 Unix时间戳(Unix timestamp)
    关于'跳墙'
    webex js 判断是否是ie 以及兼容性代码
    VLOOKUP函数对查找内容列排序增加效率
    netsuite动态绑定事件
    netsuite filter的选择框 代码控制
    html js 跨域 p3p
    netsuite 记录类型 权限分配 use permissions
  • 原文地址:https://www.cnblogs.com/yaowen/p/11776995.html
Copyright © 2020-2023  润新知