A detailed XML approach to the parsing of spring AOP

Source: Internet
Author: User

<aop:config> Label parsing

The parser for the AOP namespace is Aopnamespacehandler

Here we can see a few parsers registered, focusing on Configbeandefinitionparser

In the parse method of Configbeandefinitionparser, the following three direct sub-tags pointcut, advisor, Aspect, respectively, are parsed aop:config

list<element> childelts = domutils.getchildelements (Element);        For (Element elt:childelts) {            String localname = parsercontext.getdelegate (). Getlocalname (ELT);            If (Pointcut.equals (localname)) {                parsepointcut (ELT, ParserContext);            }            else if (Advisor.equals (localname)) {                parseadvisor (ELT, ParserContext);            }            else if (Aspect.equals (localname)) {Parseaspect (ELT, ParserContext);}}     
Pointcut Label parsing
PrivateAbstractbeandefinition 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)); 
Create Beandefinition, below pointcutdefinition = createpointcutdefinition (expression); Pointcutdefinition.setsource (Parsercontext.extractsource (pointcutelement)); String pointcutbeanname = id; if (Stringutils.hastext (pointcutbeanname)) {
//This is the registered bean Parsercont Ext.getregistry (). Registerbeandefinition (Pointcutbeanname, pointcutdefinition); } else {pointcutbeanname = parsercontext.getreadercontext (). Registerwithgeneratedname ( Pointcutdefinition); } parsercontext.registercomponent (New pointcutcomponentdefinition (Pointcutbeanname, Pointcutdefinition, expression)); Finally {this . Parsestate.pop ();} return pointcutdefinition;
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;    }   

We can see that the beanclass of Rootbeandefinition is Aspectjexpressionpointcut, that is, Getbean will instantiate Aspectjexpressionpointcut, and set a property value for it expression such as execution (* com.wjz.service.*.* (..))

Let's take a look at the inheritance structure of aspectjexpressionpointcut. This class implements both the Classfilter and Methodmatcher interfaces to perform class matching and method matching logic. It has an expression property to set expressions, and ASPECTJ will eventually parse the expression into a Pointcutexpression object to perform the related semantics. The following article is detailed

Aspect label parsing

The parsing of the aspect tag is relatively complex, parsing all the notification sub-labels (aop:before, aop:after, etc.) below it

String Aspectid =Aspectelement.getattribute (ID); String Aspectname =Aspectelement.getattribute (REF);
Get all Notifications sub-label NodeList NodeList =Aspectelement.getchildnodes (); Boolean Advicefoundalready = False; for (int i = 0; i < nodelist.getlength (); i++) {Node node =Nodelist.item (i);
Determine if the notification label is before,after-returning 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));}
Parse and register the notification sub-label, following the detailed 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) {parsepointcut (pointcutelement, parsercontext);} Parsercontext.popandregistercontainingcomponent ();
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))); The method attribute of the notification tag is parsed into a methodlocatingfactorybean type Bean, and the MethodName property value is set to 
// Prepare for the formal parameters of a constructor such as Aspectjmethodbeforeadvice
rootbeandefinition methoddefinition = new Rootbeandefinition (MethodL Ocatingfactorybean.class ); Methoddefinition.getpropertyvalues (). Add ("Targetbeanname" , aspectname); methoddefinition.getpropertyvalues (). Add ("MethodName", Adviceelement.getattribute ("method" )); Methoddefinition.setsynthetic (true );// Create an instance of Aspectinstancefactory to prepare the formal parameters for constructors such as Aspectjmethodbeforeadvice
Rootbeandefinition aspectfactorydef = new Rootbeandefinition (simplebeanfactoryawareaspectinstancefactory.class); Aspectfactorydef.getpropertyvalues (). Add ("Aspectbeanname", aspectname); Aspectfactorydef.setsynthetic (True); Prepare the constructor for Aspectjmethodbeforeadvice, and then abstractbeandefinition advicedef = createadvicedefinition (adviceelement, ParserContext, Aspectname, order, methoddefinition, Aspec            Tfactorydef, Beandefinitions, beanreferences); The resolution notification sub-label is Aspectjpointcutadvisor object rootbeandefinition advisordefinition = new Rootbeandefinition (ASPECTJPOINTC            Utadvisor.class ); Advisordefinition.setsource (Parsercontext.extractsource (adviceelement)); 
//Set constructor parameter information for Abstractaspectjadvice in Aspectjpointcutadvisor advisordefinition.getconstructorargument Values (). Addgenericargumentvalue (Advicedef); If (Aspectelement.hasattribute (Order_property)) {advisordefinition.getpropertyvalues (). Add (ORDER_PROPERTY, Aspectelement.getattribute (Order_property)); }//Register notification sub-label Parsercontext.getreadercontext (). Registerwithgeneratedname (advisordefinition); return Advisordefinition; Finally {this . Parsestate.pop ();}}
PrivateAbstractbeandefinition createadvicedefinition (Element adviceelement, ParserContext parsercontext, String aspec Tname, intOrder, Rootbeandefinition MethodDef, Rootbeandefinition aspectfactorydef, list<beandefinition> Beandefinitions, list<beanreference>beanreferences) {//Getadviceclass () method get Aspectjmethodbeforeadvice, Aspectjafterreturningadvice, etc. RootBeanDefinit Ion advicedefinition = newRootbeandefinition (Getadviceclass (adviceelement, ParserContext));     Advicedefinition.setsource (Parsercontext.extractsource (adviceelement));        Add attribute Value 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 (R        eturning)); } 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));} Prepare the parameters required for the constructor such as Aspectjmethodbeforeadvice, prepare the Aspectjmethodbeforeadvice for the reflection of the constructor constructorargumentvalues CAV =advicedefinition.getconstructorargumentvalues (); Cav.addindexedargumentvalue (Method_index, METHODDEF); Get Pointcut-ref Property value Object pointcut = parsepointcutproperty (adviceelement, ParserContext); if (Pointcut instanceof beandefinition) {Cav.addindexedargumentvalue (Pointcut_index, POINTCUT); Beandefinitions.add ((beandefinition) POINTCUT);} else if (pointcut instanceof String) {runtimebeanreference pointcutref = new runtimebeanreference ((String) point CUT); Cav.addindexedargumentvalue (Pointcut_index, pointcutref); Beanreferences.add (POINTCUTREF); } cav.addindexedargumentvalue (Aspect_instance_factory_index, aspectfactorydef); return advicedefinition;}     

The constructor for the Aspectjmethodbeforeadvice is

Advisor Tag Parsing
private voidParseadvisor (Element advisorelement, ParserContext parsercontext) {
Create the advisor tag corresponding to the beandefinition, followed by a detailed abstractbeandefinition advisordef =Createadvisorbeandefinition (Advisorelement, ParserContext); String ID =Advisorelement.getattribute (ID); Try{This.parseState.push (newAdvisorentry (ID)); String Advisorbeanname = ID;
//Register Bean if (Stringutils.hastext (advisorbeanname)) {parsercontext.getregistry (). registerbeandefinition (Advisorbeanname, Advisordef);       } else {advisorbeanname = parsercontext.getreadercontext (). Registerwithgeneratedname (advisordef);} Get the Pointcut-ref property value, add the property Object pointcut = parsepointcutproperty (advisorelement, ParserContext), if (pointcut instanceof beandefinition) {advisordef.getpropertyvalues (). Add (POINTCUT, POINTCUT); Parsercontext.registercomponent (New advisorcomponentdefinition (Advisorbeanname, Advisordef, (BeanDefinition ) (pointcut)); } else if (pointcut instanceof String) {advisordef.getpropertyvalues (). Add (pointcut, new Runtimebeanreference ((String) pointcut)); Parsercontext.registercomponent (New advisorcomponentdefinition (Advisorbeanname, Advisordef));}} Finally {this . Parsestate.pop ();}}
PrivateAbstractbeandefinition createadvisorbeandefinition (Element advisorelement, ParserContext ParserContext) {
Getbean when instantiating a defaultbeanfactorypointcutadvisor rootbeandefinition advisordefinition = new RootBeanDefinition (Def Aultbeanfactorypointcutadvisor.class); Advisordefinition.setsource (Parsercontext.extractsource (advisorelement)); String adviceref = advisorelement.getattribute (advice_ref); if (! Stringutils.hastext (Adviceref)) {Parsercontext.getreadercontext (). Error ("' Advice-ref ' attr Ibute contains empty value. ", Advisorelement, this. Parsestate.snapshot ()); } else {advisordefinition.getpropertyvalues (). Add (Advice_bean_name, New runtimebeannamereference (adviceRe f)); } If (Advisorelement.hasattribute (Order_property)) {advisordefinition.getpropertyvalues (). Add (ORDER_PROPERTY, Advisorelement.getattribute (Order_property)); } return advisordefinition;}

A detailed XML approach to the parsing of spring AOP

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.