Spring Technology Insider: The implementation principle of Spring AOP (I.)

Source: Internet
Author: User
Tags throwable

I. Overview of SPRINGAOP
1. AOP Concept
AOP is the abbreviation for aspect-oriented programming (plane-oriented programming). Wikipedia explains the following:
Aspect is a new modular mechanism for describing crosscutting concerns (crosscutting concern) scattered across objects, classes, or functions. The separation of the crosscutting concerns from the point of concern is the core of the program design oriented to the aspect. Separation of concerns enables code that solves a particular domain problem to be independent of the business logic code, where the code of the business logic no longer contains calls to specific code for the picking problem, and the relationship between business logic and a particular domain problem is encapsulated and maintained by facets, so that changes that are scattered throughout the application can be managed well.
2, advice notice
The advice definition provides a weaving interface for aspect enhancement at the connection point. In spring AOP, he mainly describes the tangent behavior that spring AOP injects around method invocations. Advice is the interface defined in Org.aopalliance.aop.Advice. This unified interface is used in spring AOP, and this interface provides additional details and extensions for AOP aspect-enhanced weaving capabilities, such as providing a more specific type of notification, such as Beforeadvice,afteradvice,throwsadvice.
2.1 Beforeadvice
First we start with the Beforeadvice:
In the inheritance relationship of Beforeadvice, the pre-enhanced interface Methodbeforeadvice for the target method to be enhanced is defined, and a callback function is implemented using this predecessor interface:

void before(Method method,Object[] args,Object target) throws Throwable;

As a callback function, the implementation of the Before method is configured in advice to the target method and is called back when the target method is invoked. The specific parameters are: Method object, which is the reflection object of the target method; An array of object[] objects containing the input parameters of the target method. Taking Countingbeforeadvice as an example to illustrate the specific use of Beforeadvice, Countbeforeadvice is the implementation of the interface Methodbeforeadvice, he just counted the number of times the method was called, as a facet enhancement implementation , he will make statistics based on the method name of the calling method, and put the statistical results into a map based on the method name and the number of calls as key-value pairs. The code is as follows:

 Public  class countingbeforeadvice extends methodcounter  implements  Methodbeforeadvice {    //Implement method of Methodbeforeadvice interface with pre-notification     Public void before(Method m, object[] args, Object target)throwsThrowable {//using the target object method as a parameter, call the Count method of the parent class Methodcounter to count the number of method callsCount (m); The source code of}}countingbeforeadvice's parent methodcounter is as follows: Public  class methodcounter implements Serializable {    Map Collection of method calls, method name, number of calls to the stored method    Privatehashmap<string, integer> map =NewHashmap<string, integer> ();//Total number of calls for all methods    Private intAllcount;//Statistics method call number, Countingbeforeadvice call entry    protected void Count(Method m)    {count (M.getname ()); }//Statistics The number of calls to the specified name method    protected void Count(String methodName) {//Gets the number of invocations of the specified name method from the collection of method invocation number , method nameInteger i = Map.get (methodName);//If the number of calls is not NULL, the number of calls is added to 1, and if the number of calls is NULL, the number of calls is set to 1i = (i! =NULL) ?NewInteger (I.intvalue () +1) :NewInteger (1);//Reset the number of method calls saved in the collectionMap.put (MethodName, i);//Total number of calls to all methods plus 1++allcount; }//Gets the number of calls to the specified name method     Public int Getcalls(String methodName) {Integer i = map.get (methodName);return(I! =NULL? I.intvalue ():0); }//Gets the total number of calls for all methods     Public int Getcalls() {returnAllcount; } Public Boolean equals(Object Other) {return(Other! =NULL&& Other.getclass () = = This. GetClass ()); } Public int hashcode() {returnGetClass (). Hashcode (); }}

2.2 Afteradvice
In the advice implementation system, Spring also provides afteradvice this type of notification, here the implementation of Afterreturningadvice notification as an example, the code is as follows:

publicinterface AfterReturningAdvice extends AfterAdvice {//后置通知的回调方法,在目标方法对象调用结束并成功返回之后调用// returnValue参数为目标方法对象的返回值,method参数为目标方法对象,args为    //目标方法对象的输入参数    voidthrows Throwable;}

The Afterreturning method is also a callback function, the AOP application needs to provide the aspect enhancement in this interface implementation the concrete design, after this advice notification is configured correctly, when the target method call ends and returns successfully, the interface is called by SPRINGAOP. As in the previous analysis, in the Spring AOP package, you can see the Countingafterreturningadvice, which is basically the same:

public   class  countingafterreturningadvice  extends  methodcounter  implements  afterreturningadvice  { //implement callback method for post-notification afterreturningadvice  public
      void  afterreturning  (Object o, Method m, Object[] args, Object target) throws  throwable {//call Parent    The count method of the class Methodcounter, the number of calls to the statistics method  count (m); }}

In the interface method afterreturning that implements Afterreturningadvice, you can call the Count method of Methodcounter to complete the count of the number of target method calls based on the method name.
2.3 Throwsadvice
Let's take a look at another type of advice notification Throwsadvice. For Throwsadvice, there is no interface method that needs to be implemented, he is called back when throwing an exception, and this callback is done using the reflection mechanism of AOP. You can use Countingthrowsadvice to understand how throwsadvice is used:

 Public Static  class countingthrowsadvice extends methodcounter  implements  Throwsadvice {        //When throwing an IO-type exception, the number of times the exception is called is counted         Public void afterthrowing(IOException ex)throwsThrowable {count (IOException.class.getName ()); }//When throwing a callback method with an Uncheckedexception type exception, count the number of times the exception was called         Public void afterthrowing(Uncheckedexception ex)throwsThrowable {count (UncheckedException.class.getName ()); }    }

3. Pointcut Tangent Point
Determines which connection point the advice notification should act on, that is, by pointcut to define a collection of methods that need to be enhanced, the selection of these collections can be done in accordance with certain rules. Pointcut often means identifying methods, for example, where these need to be enhanced can be identified by a regular expression, or matched according to a method name. The source code is as follows:

publicinterface Pointcut {    //获取类过滤器    ClassFilter getClassFilter();    //获取匹配切入点的方法        MethodMatcher getMethodMatcher();    //总匹配的标准切入点实例    

Looking at the inheritance system of Pointcut pointcuts, it is found that the implementation classes of Pointcut pointcuts are very many, such as annotationmatchingpointcut for annotation configuration, jdkregexpmethodpointcut for regular expressions, etc. We take jdkregexpmethodpointcut as an example to analyze the specific implementation of pointcut matching, the source code is as follows:

 Public  class jdkregexpmethodpointcut extends abstractregexpmethodpointcut {    //Regular expression pattern to compile    Privatepattern[] Compiledpatterns =Newpattern[0];//compile-time regular expression pattern to exclude    Privatepattern[] Compiledexclusionpatterns =Newpattern[0];//Initializes the given pattern string array to the compiled regular expression pattern    protected void initpatternrepresentation(string[] patterns)throwspatternsyntaxexception { This. Compiledpatterns = Compilepatterns (patterns); }//Initializes the given pattern string array to the regular expression pattern to be excluded at compile-time    protected void initexcludedpatternrepresentation(string[] excludedpatterns)throwspatternsyntaxexception { This. Compiledexclusionpatterns = Compilepatterns (excludedpatterns); }//Use regular expression to match given name    protected Boolean matches(String pattern,intPatternindex) {Matcher Matcher = This. Compiledpatterns[patternindex].matcher (pattern);returnMatcher.matches (); }//Use the regular expression you want to exclude to match the given name    protected Boolean matchesexclusion(String candidate,intPatternindex) {Matcher Matcher = This. Compiledexclusionpatterns[patternindex].matcher (candidate);returnMatcher.matches (); }//compiles the given string array into a regular expression pattern    PrivatePattern[]Compilepatterns(string[] source)throwspatternsyntaxexception {pattern[] destination =NewPattern[source.length]; for(inti =0; i < source.length;        i++) {Destination[i] = Pattern.compile (Source[i]); }returnDestination }}

4. Advisor notification Device
After completing the Aspect enhancement Design (Advice) and the design of the focus (Pointcut) for the target method, you need an object to combine them, and the advisor is the way to do it. Through he can define which notification should be used and at which point of interest to use it. There are two properties in defaultpointcutadvisor, namely advice and pointcut. These two properties allow you to configure advice and pointcut, respectively. The source code is as follows:

 Public  class defaultpointcutadvisor extends  abstractgenericpointcutadvisor  Implements Serializable {    //default Pointcut    //pointcut.true is defined in the Pointcut as: Pointcut TRUE = truepointcut.instance;    PrivatePointcut Pointcut = pointcut.true;//No parameter construction method, create an empty notifier     Public Defaultpointcutadvisor() {    }//Create a notifier that matches all methods     Public Defaultpointcutadvisor(Advice Advice) { This(pointcut.true, advice); }//Create a notifier that specifies pointcuts and notifications     Public Defaultpointcutadvisor(Pointcut Pointcut, Advice Advice) { This. pointcut = Pointcut;    Setadvice (advice); }//Set pointcuts for notifications     Public void Setpointcut(Pointcut Pointcut) { This. Pointcut = (pointcut! =NULL?    Pointcut:Pointcut.TRUE); }//Get pointcuts     PublicPointcutGetpointcut() {return  This. pointcut; } PublicStringtoString() {returnGetClass (). GetName () +": pointcut ["+ getpointcut () +"]; Advice ["+ getadvice () +"]"; }}

In the above source, the default entry point of the notifier is pointcut.true,pointcut.true in the pointcut is defined as: Pointcut TRUE = truepointcut.instance
The instance of Truepointcut is a single piece, such as using the static class variable to hold a single instance, using the private proprietary constructor to ensure that a single piece is not created and instantiated again except in the current single implementation.
The implementation of Truepointcut and Truemethodmatcher is as follows:

/** * Canonical Pointcut instance that always matches. * * @author Rod Johnson * *@SuppressWarnings("Serial") class Truepointcut implements Pointcut, Serializable { Public Static FinalTruepointcut INSTANCE =NewTruepointcut ();/** * Enforce Singleton pattern. * Here is the implementation of the single-piece mode, set the private constructor, so that it can not be directly instantiated * and set a static class variable to ensure that the instance is unique * /    Private Truepointcut() {    } PublicClassfilterGetclassfilter() {returnClassfilter.true; } PublicMethodmatcherGetmethodmatcher() {returnMethodmatcher.true; }/** * Required to support serialization.     Replaces with canonical * instance on deserialization, protecting Singleton pattern.     * Alternative to overriding {@code equals ()}. */    PrivateObjectReadresolve() {returnINSTANCE; }@Override     PublicStringtoString() {return "Pointcut.true"; }}
/** * Canonical Methodmatcher instance that matches all methods. * * @author Rod Johnson * *@SuppressWarnings("Serial") class Truemethodmatcher implements Methodmatcher, Serializable { Public Static FinalTruemethodmatcher INSTANCE =NewTruemethodmatcher ();/** * Enforce Singleton pattern. */    Private Truemethodmatcher() {    } Public Boolean Isruntime() {return false; } Public Boolean matches(method, Class Targetclass) {return true; } Public Boolean matches(method, Class Targetclass, object[] args) {//Should never be invoked as Isruntime returns false.        Throw NewUnsupportedoperationexception (); }/** * Required to support serialization.     Replaces with canonical * instance on deserialization, protecting Singleton pattern.     * Alternative to overriding {@code equals ()}. */    PrivateObjectReadresolve() {returnINSTANCE; }@Override     PublicStringtoString() {return "Methodmatcher.true"; }}

Next we begin to learn what spring AOP is all about
To be Continued ...

Spring Technology Insider: The implementation principle of Spring AOP (I.)

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.