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:引用的名字, } }