SPRINGAOP Source Code Analysis

Source: Internet
Author: User

SPRINGAOP implementation for dynamic agent implementation, there are 2 ways, JDK dynamic agent and Cglib dynamic agent
First write an AOP case to illustrate
The configuration file code is:

    class= "Com.spring.aop.service.UserDaoImpl"/>        class= "Com.spring.aop.log.Logger"/>        <!--facets: pointcuts and Notifications-    <aop:config>        <aop:aspect id= "aspect"  ref= "Logger" >            < Aop:pointcut expression= "Execution (* com.spring.aop.service. *.*(..))" Id= "Udpateusermethod"/>            <aop:before method= "Recordbefore" pointcut-ref= "Udpateusermethod"/>            <aop:after method= "Recordafter"   pointcut-ref= "Udpateusermethod"/>        </aop:aspect>    < /aop:config>

The implementation of the enhanced class logger is:

 Package Com.spring.aop.log;  Public class Logger {     publicvoid  Recordbefore () {            System.out.println ("Recordbefore ");        }                  Public void Recordafter () {            System.out.println ("Recordafter");        }    

The implementations of the safeguarded class Userdaoimpl and the safeguarded class interface are:

 PackageCom.spring.aop.service; Public InterfaceUserdao {voidAddUser (); voiddeleteuser ();} PackageCom.spring.aop.service; Public classUserdaoimplImplementsUserdao {@Override Public voidAddUser () {System.out.println ("Add User"); } @Override Public voidDeleteUser () {System.out.println ("Delete User"); }}

Test method Code:

 PackageCom.spring.aop.main;ImportOrg.springframework.context.support.ClassPathXmlApplicationContext;ImportCom.spring.aop.service.UserDao; Public classTESTAOP { Public Static voidMain (string[] args) {Classpathxmlapplicationcontext ApplicationContext=NewClasspathxmlapplicationcontext ("Springaop.xml");//beandefination Parsing registration, generation of proxy objectsUserdao Userdao = (Userdao) applicationcontext.getbean ("Userdao");//you can see that the Userdao type starts with $proxy, and the description is obtained by means of the JDK dynamic proxy.Userdao.adduser ();//the moment when the act of enhancement occurs    }}

Operation Result:

It can be seen that the target method has been enhanced.

The following begins the source analysis from the Spring XML parsing

Starting with the Parsebeandefinitions method of the Defaultbeandefinitiondocumentreader class, the analysis The Parsebeandefinitions method is divided into spring default label parsing and custom label parsing, where the label <aop:config> is parsed using custom tag parsing, the code is as follows:

     Publicbeandefinition parsecustomelement (Element ele, beandefinition containingbd) {String NamespaceURI=Getnamespaceuri (ele); Namespacehandler Handler= This. Readercontext.getnamespacehandlerresolver (). Resolve (NamespaceURI); if(Handler = =NULL) {error ("Unable to locate Spring Namespacehandler for XML schema namespace [" + NamespaceURI + "]", ele); return NULL; }
At this point, handler refers to the Configbeandefinitionparser objectreturnHandler.parse (Ele,NewParserContext ( This. Readercontext, This, CONTAININGBD)); }

The following parse method enters the Configbeandefinitionparser object for analysis:

@Override PublicBeandefinition Parse (element element, ParserContext parsercontext) {compositecomponentdefinition compositedef =Newcompositecomponentdefinition (Element.gettagname (), Parsercontext.extractsource (Element));        Parsercontext.pushcontainingcomponent (COMPOSITEDEF);        Configureautoproxycreator (parsercontext, Element); 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); }
Parse the aspect tag hereElse if(Aspect.equals (localname)) {Parseaspect (ELT, ParserContext); }} parsercontext.popandregistercontainingcomponent (); return NULL; }

    Private voidParseaspect (Element aspectelement, ParserContext parsercontext) {//gets the ID defined above the aspect labelString Aspectid =Aspectelement.getattribute (ID); //Gets the aspect tags referenced above for the enhanced class loggerString Aspectname =Aspectelement.getattribute (REF); Try {            //encapsulates the Aspectid and aspectname into Aspectentry objects and puts them into the stack parsestate             This. Parsestate.push (Newaspectentry (Aspectid, aspectname)); //enclose the information related to <aop:before> and other notifications in aspectjpointcutadvisor and put it in the collectionList<beandefinition> beandefinitions =NewArraylist<beandefinition>(); //encapsulate ref-related information, such as Logger,updateusermethod in Aop.xml, into runtimebeanreference and put it in this collectionList<beanreference> beanreferences =NewArraylist<beanreference>(); List<Element> declareparents =domutils.getchildelementsbytagname (aspectelement, declare_parents);  for(inti = 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.NodeList NodeList =aspectelement.getchildnodes (); BooleanAdvicefoundalready =false; //loop to determine whether the child node is a notification, if it is a notification to the corresponding processing             for(inti = 0; I < nodelist.getlength (); i++) {node node=Nodelist.item (i); if(Isadvicenode (node, parsercontext)) {if(!Advicefoundalready) {                        //Advicefoundalready guaranteed to just put a quote onceAdvicefoundalready =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 (Newruntimebeanreference (aspectname)); }                    //encapsulates the notification information into the Aspectjpointcutadvisor class, encapsulating the ref information and putting it in the beanreferencesAbstractbeandefinition advisordefinition =Parseadvice (Aspectname, I, Aspectelement, (Element) node, ParserContext, Beandefinitions,                    Beanreferences);                Beandefinitions.add (advisordefinition); }            }            //Encapsulation of slice information and notification information into this classAspectcomponentdefinition aspectcomponentdefinition =createaspectcomponentdefinition (aspectelement, Aspectid, Beandefinitions, Beanreferences, ParserC            Ontext);            Parsercontext.pushcontainingcomponent (aspectcomponentdefinition); List<Element> pointcuts =domutils.getchildelementsbytagname (aspectelement, POINTCUT);  for(Element pointcutelement:pointcuts) {//parse a specific entry pointparsepointcut (pointcutelement, ParserContext);        } parsercontext.popandregistercontainingcomponent (); }        finally {             This. Parsestate.pop (); }    }


Finally, the information about the <aop:config> configuration is encapsulated into a class and then put into the containingcomponents stack for easy operation later

SPRINGAOP Source Code Analysis

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.