AOP Source Parsing (iii) gain of the enhancer

Source: Internet
Author: User
Tags aop static class

The acquisition logic of the common intensifier is realized by the Getadvisor method, which includes the acquisition of the annotation of the tangent point and the generation of the enhancement based on the annotation information.

    Public Advisor getadvisor (Method candidateadvicemethod, metadataawareaspectinstancefactory AIF, int Declarationorderinaspect, String aspectname)
    {
        Validate (Aif.getaspectmetadata (). Getaspectclass ());
        Get the Pointcut information
        aspectjexpressionpointcut ajexp = Getpointcut (Candidateadvicemethod, Aif.getaspectmetadata (). Getaspectclass ());
        if (ajexp = = null)
            return null;
        else
            //Generate an enhancer from the Pointcut information
            return new Instantiationmodelawarepointcutadvisorimpl (this, Ajexp, AIF, Candidateadvicemethod, Declarationorderinaspect, aspectname);
    }

(1) Get the tangent information. The so-called Get tangency information is the acquisition of the expression information of the specified annotation, such as @before ("Test ()")

    Private Aspectjexpressionpointcut Getpointcut (Method candidateadvicemethod, Class candidateaspectclass)
    {
        / /Get Annotations on the method
        abstractaspectjadvisorfactory.aspectjannotation aspectjannotation = Abstractaspectjadvisorfactory.findaspectjannotationonmethod (Candidateadvicemethod);
        if (aspectjannotation = = null)
        {
            return null;
        } else
        {
            //Use Aspectjexpressionpointcut instance to encapsulate the information obtained
            aspectjexpressionpointcut ajexp = new Aspectjexpressionpointcut (Candidateaspectclass, New String[0], new Class[0 ]);
            The expressions in the extracted annotations are as follows: @Pointcut ("Execution (* *.*test* (..))" ) in the execution (* *.*test* (..)) <pre name= "code" class= "Java" >   

))
Ajexp.setexpression (Aspectjannotation.getpointcutexpression ()); return ajexp; } }

protected static Aspectjannotation Findaspectjannotationonmethod (method)
    {
        //Set up sensitive annotation classes class
        Classestolookfor[] = {
            Org/aspectj/lang/annotation/before, Org/aspectj/lang/annotation/around, org/aspectj/ Lang/annotation/after, org/aspectj/lang/annotation/afterreturning, org/aspectj/lang/annotation/afterthrowing, org /aspectj/lang/annotation/pointcut
        };
        for (class< extends annotation> c:classsestolookfor)
        {
            Aspectjannotation foundannotation = Findannotation (method, c);
            if (foundannotation! = null)
                return foundannotation;
        }

        return null;
    }
Gets the annotations on the specified method and uses the Aspectjannotation encapsulation
    private static Aspectjannotation Findannotation (method, Class tolookfor)
    {
        Annotation result = Annotationutils.findannotation (method, tolookfor);
        if (result = null)
            return new aspectjannotation (result);
        else
            return null;
    }
(2) Generate enhancements based on tangency information. All enhancements have the Advisor implementation class Instantiationmodelawarepontcutadvisorimpl unified soaring.
 public Instantiationmodelawarepointcutadvisorimpl (Aspectjadvisorfactory AF, Aspectjexpressionpointcut Ajexp, Metadataawareaspectinstancefactory AIF, method method, int declarationorderinaspect,
        String aspectname) {declaredpointcut = Ajexp;
        This.method = method;
        ataspectjadvisorfactory = AF;
        Aspectinstancefactory = AIF;
        Declarationorder = Declarationorderinaspect;
        This.aspectname = Aspectname; if (Aif.getaspectmetadata (). islazilyinstantiated ()) {Pointcut preinstantiationpointcut = Pointcuts.uni
            On (Aif.getaspectmetadata (). Getperclausepointcut (), declaredpointcut);
            Pointcut = new Pertargetinstantiationmodelpointcut (declaredpointcut, Preinstantiationpointcut, AIF);
        Lazy = true;
            } else {instantiatedadvice = Instantiateadvice (declaredpointcut);
            Pointcut = Declaredpointcut;
        Lazy = false; }
    }

The encapsulation process simply encapsulates the information in an instance of the class, and all the amount of information is simply copied. Initialization of the enhancer is also done during instance initialization. Because the logic of different enhancements is different, such as the @before ("Test ()") and the After ("Test ()") tags are different in the position of the enhancer enhancement, so you need a different enhancer to complete the different logic, The corresponding amount enhancer is implemented in the Instantiateadvice function based on the information in the annotations.
    Private Advice Instantiateadvice (aspectjexpressionpointcut pcut)
    {
        return Ataspectjadvisorfactory.getadvice (method, Pcut, Aspectinstancefactory, Declarationorder, aspectname);
    }

Public Advice Getadvice (Method candidateadvicemethod, Aspectjexpressionpointcut ajexp, Metadataawareaspectinstancefactory AIF, int declarationorderinaspect, String aspectname) {Class Candidateaspe
        Ctclass = Aif.getaspectmetadata (). Getaspectclass ();
        Validate (Candidateaspectclass); Abstractaspectjadvisorfactory.aspectjannotation aspectjannotation =
        Abstractaspectjadvisorfactory.findaspectjannotationonmethod (Candidateadvicemethod);
       if (aspectjannotation = = null) return null; If we get here,we know we have a AspectJ method. Check that it an aspectj-annotated class if (!isaspect (Candidateaspectclass)) throw new Aopconfigexcep tion (new StringBuilder ()). Append ("Advice must is declared inside an aspect type:offending method '"). Append (Candidatead
        Vicemethod). Append ("' in class ["). Append (Candidateaspectclass.getname ()). Append ("]"). ToString ()); if (logger.isdebugenabled ()) Logger.debug (New StringbuiLder ()). Append ("Found AspectJ Method:"). Append (Candidateadvicemethod). toString ());
 abstractaspectjadvice Springadvice;         switch (_CLS4. switchmap.org.springframework.aop.aspectj.annotation.abstractaspectjadvisorfactory.aspectjannotationtype[ Aspectjannotation.getannotationtype (). Ordinal ())         {         Case 1://' \001 '            
Springadvice = new Aspectjmethodbeforeadvice (Candidateadvicemethod, Ajexp, AIF);

            break;         Case 2://' \002 '          
   springadvice = new Aspectjafteradvice (Candidateadvicemethod, Ajexp, AIF);

            break;         Case 3://' \003 '             springadvice = new
Aspectjafterreturningadvice (Candidateadvicemethod, Ajexp, AIF);             afterreturning afterreturningannotation = (
afterreturning) aspectjannotation.getannotation ();             if (Stringutils.hastext ( Afterreturningannotation.returning ()))             
    Springadvice.setreturningname (afterreturningannotation.returning ());

            break;         Case 4://' \004 '          
   springadvice = new Aspectjafterthrowingadvice (Candidateadvicemethod, Ajexp, AIF);             afterthrowing afterthrowingannotation = (afterthrowing) aspectjannotation.getannotation ();             if (Stringutils.hastext ( Afterthrowingannotation.throwing ()))             
    Springadvice.setthrowingname (afterthrowingannotation.throwing ());

            break;         Case 5://' \005 '          
   springadvice = new Aspectjaroundadvice (Candidateadvicemethod, Ajexp, AIF);

            break;         Case 6://' \006 '              if (logger.isdebugenabled ())                  Logger.debug ((New StringBuilder ()). Append ("Processing pointcut' "). Append (Candidateadvicemethod.getname ()). Append (" ' "). toString ());

            return null;         Default:              Throw new Unsupportedoperationexception ((New StringBuilder ()). Append ("Unsupported advice type on method").
Append (Candidateadvicemethod). toString ());        }        
Springadvice.setaspectname (Aspectname);
        Springadvice.setdeclarationorder (Declarationorderinaspect);         String argnames[] = Parameternamediscoverer.getparameternames (
Candidateadvicemethod);         if (argNames! = null)         
    Springadvice.setargumentnamesfromstringarray (argNames);         springadvice.calculateargumentbindings ();
        return springadvice;    }}
As you can see from the function, spring will generate different enhancers based on different annotations, for example Atbefore will correspond to Aspectjmethodbeforeadvice.

2. Add Synchronous instantiation Enhancer

If you are looking for an enhancer that is not empty and is configured for enhanced lazy initialization, then you need to join the synchronous instantiation Enhancer first. Synchronous instantiation Enhancer Syntheticinstantiationadvisor, as follows:

Protected static class Syntheticinstantiationadvisor extends Defaultpointcutadvisor
    {

        public Syntheticinstantiationadvisor (Final metadataawareaspectinstancefactory AIF)
        {
            super ( Aif.getaspectmetadata (). Getperclausepointcut (), new Methodbeforeadvice () {
                //current method before call, similar to @before public
                void Before (method, object args[], object target)
                {   //simple initialization of Aspect
                    aif.getaspectinstance ();
                }

3. Get declareparents Annotations


Declareparents is mainly used for the introduction of enhanced annotation form implementation, and its implementation is similar to the general enhancement, but using declareparentsadvisor to encapsulate the function.

    Private Advisor Getdeclareparentsadvisor (Field Introductionfield)
    {
        declareparents declareparents = ( declareparents) introductionfield.getannotation (org/aspectj/lang/annotation/declareparents);
        if (declareparents = = null)
            return null;
        if (Org/aspectj/lang/annotation/declareparents.equals (Declareparents.defaultimpl ()))
            throw new IllegalStateException ("Defaultimpl must is set on Declareparents");
        else
            return new Declareparentsadvisor (Introductionfield.gettype (), Declareparents.value (), Declareparents.defaultimpl ());
    }
In the following section, we will analyze how spring looks for a matching enhancer, longer and more complex, but still want us to look at it, because the process is hard, and after that, you'll find that the harvest is huge.


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.