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.