Spring (iii)--AOP "aspect-oriented programming", notification types and usage, pointcut expressions

Source: Internet
Author: User
Tags getmessage mul throwable

1. Concept: Aspect oriented programming aspect-oriented programming before and after methods 2. Role: Essentially a way to simplify code
Inheritance mechanism
Encapsulation method
Dynamic Agent
......

3. Examples of scenarios
① Math Calculator interface [Mathcalculator]
int Add (int i,int j);
int sub (int i,int j);
int mul (int i, int j); int div (int i,int j); Because the subsequent notification method requires a return value, the type declared here is of type int
Public interface Mathcaculator {public      int Add (int i,int j);      public int sub (int i,int j);      public int Mul (int i,int j);      public int div (int i,int j);}
② provides a simple implementation [Easyimpl] Be sure to write annotations on the class, otherwise not found in the IOC container
@Componentpublic class Cacultoreasyimpl implements mathcaculator{      @Override public      void Add (int i, int j) {            SYSTEM.OUT.PRINTLN ("[log]," parameter: "+i+", "+j");            int result = i + j;            SYSTEM.OUT.PRINTLN ("[log]," parameter: "+i+", "+j+"--"+result");      @Override Public      void Sub (int i, int j) {            System.out.println ("[Log]," "Parameter:" "+i+", "+j");            int result = I-j;            SYSTEM.OUT.PRINTLN ("[log]," parameter: "+i+", "+j+"--"+result");      @Override public      void Mul (int i, int j) {            System.out.println ("[log]," parameter: "" +i+ "," +j ");            int result = i * j;            SYSTEM.OUT.PRINTLN ("[log]," parameter: "+i+", "+j+"--"+result");      @Override public      void Div (int i, int j) {            System.out.println ("[Log]," "Parameter:" "+i+", "+j");            int result = i/j;            SYSTEM.OUT.PRINTLN ("[log]," parameter: "+i+", "+j+"--"+result);      }}

<context:component-scan base-package= "COM.NEUEDU.AOP" ></context:component-scan>

③ enables each calculation method to print logs on a simple implementation basis [Loginimpl]

Private ApplicationContext IOC = new Classpathxmlapplicationcontext ("Applicationcontext.xml"); @Testpublic void Test () {      Cacultoreasyimpl bean = Ioc.getbean (cacultoreasyimpl.class);      Bean.add (ten, 2);      Bean.sub (ten, 2);      Bean.mul (ten, 2);      Bean.div (10, 2);}

④ defects
[1] Manual add log tedious, repetitive
[2] Unified modification inconvenience
[3] The target method is to achieve the core function has interference, make the program code is very bloated, not easy to develop and maintain

⑤ using dynamic proxy implementations
[1] Create a class that enables this class to provide a proxy object for a target object
[2] Print the log in the proxy object

4.AOP Terminology! [See Illustrations and Doc documents]
AOP Overview
AOP (aspect-oriented programming, facet-oriented programming): A new methodology complements traditional OOP (object-oriented programming, object-oriented programming). See the Legends and Doc documentation to explain the various terms of AOP!
Spring's AOP can be implemented either in the form of an XML configuration or by using annotations!

5. Using AOP in spring to implement logging functionality
AOP can be implemented in ①spring using annotations or XML file configurations.
② Importing Jar Packages
Com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0. jar
com.springsource.org.aspectj.weaver-1.6.8. Release.jar
commons-logging-1.1.3. jar
Spring-aop-4.0.0.release.jar
Spring-aspects-4.0.0.release.jar
Spring-beans-4.0.0.release.jar
Spring-context-4.0.0.release.jar
Spring-core-4.0.0.release.jar
Spring-expression-4.0.0.release. jar

③ opening annotation-based AOP features< aop:aspectj-autoproxy/>

<context:component-scan base-package= "COM.NEUEDU.AOP" ></CONTEXT:COMPONENT-SCAN><AOP: Aspectj-autoproxy/>

④ declares a slice class and joins the slice class into the IOC container.

Add the following two annotations to a class
@Aspect: Indicates that this is a slice class
@Component: Join IOC container

⑤ declaring a notification method in a slice class
[1] Pre-notification: @Before
[2] return notification: @AfterReturning
[3] Exception notification: @AfterThrowing
[4] Post notification: @After
[5] Surround Notification: @Around: Surround notification is the collective body of the front four notifications!

@Component @aspectpublic class Caculatoraspect {      @Before (value= "Execution (public void Com.neuedu.aop.RawCaculatorImpl.add (int, int)) ") Public      void Showbeginlog () {            System.out.println (" log Start ");      @After (value= "Execution (public void Com.neuedu.aop.RawCaculatorImpl.add (int, int.))") Public      Void Showreturnlog () {            System.out.println ("Log normal return");      }      @AfterThrowing (value= "Execution (public void Com.neuedu.aop.RawCaculatorImpl.add (int, int.))") Public      Void Showexceptionlog () {            System.out.println ("Log Error");      }      @AfterReturning (value= "Execution (public void Com.neuedu.aop.RawCaculatorImpl.add (int, int.))") Public      Void Showafterlog () {            System.out.println ("End of Log");}      }

⑥ the Proxied object also needs to be added to the IOC container

@Componentpublic class Rawcaculatorimpl implements mathcaculator{      @Override public      void Add (int i, int j) {            int result = i + j;            System.out.println (i+ "+" +j+ "=" +result);      }      @Override Public      void Sub (int i, int j) {            int result = I-J;            System.out.println (i+ "-" +j+ "=" +result);      }      @Override public      void Mul (int i, int j) {            int result = i * j;            SYSTEM.OUT.PRINTLN (i+ "*" +j+ "=" +result);      }      @Override public      void Div (int i, int j) {            int result = i/j;            System.out.println (i+ "/" +j+ "=" +result);}      }

Test with ID lookup, by strong turn, call subtraction four methods

Private ApplicationContext IOC = new Classpathxmlapplicationcontext ("Applicationcontext.xml"); @Testpublic void Test () {      Mathcaculator bean = (mathcaculator) ioc.getbean ("Rawcaculatorimpl");      Bean.add (ten, 2);      Bean.sub (ten, 2);      Bean.mul (ten, 2);      Bean.div (10, 2);}

6. Pointcut expression: (1) The above case through JUnit test, we will find that we call the target class of four methods only the Add method is added 4 notifications if you want all the methods to add these notifications, you can at the pointcut expression: the execution (public int Com.neuedu.aop.target.MathCalculatorImpl.add(int, int)) is replaced by: execution (public int com.neuedu.aop.target.MathCalculatorImpl. *(int, int)) This way, as long as there are two parameters, and the method with the parameter type int will execute its corresponding notification method at execution time!
@Component @aspectpublic class Caculatoraspect {      @Before (value= "Execution (public void com.neuedu.aop.rawcaculatorimpl.* (int, int)) ") Public      void Showbeginlog () {            System.out.println (" log Start ");      @After (value= "Execution (public void com.neuedu.aop.rawcaculatorimpl.* (int, int.))") Public      void Showreturnlog () {            System.out.println ("Log normal return");      }      @AfterThrowing (value= "Execution (public void com.neuedu.aop.rawcaculatorimpl.* (int, int.))") Public      Void Showexceptionlog () {            System.out.println ("Log Error");      }      @AfterReturning (value= "Execution (public void com.neuedu.aop.rawcaculatorimpl.* (int, int.))") Public      Void Showafterlog () {            System.out.println ("End of Log");}      }

If the parameter types in the method are inconsistent, you can use (..) instead (Int,int)

@Component @aspectpublic class Caculatoraspect {@Pointcut (value= "Execution (* com.neuedu.aop.rawcaculatorimpl.* (..))") public void Showlog () {} @Before (value= "Showlog ()") public void Showbeginlog (Joinpoint point) {Ob ject[] args = Point.getargs ();//Get parameter list<object> aslist = arrays.aslist (args);//Convert to List type sign Ature signature = Point.getsignature ();//Gets the signature String name = Signature.getname ();//Gets the method name System.out.      println ("Pre-Notification" target method name: "+name+", Parameter: "+aslist");      } @After (value= "Showlog ()") public void Showreturnlog () {System.out.println ("Post-Notification" log final return ");            } @AfterThrowing (value= "Showlog ()", throwing= "ex") public void Showexceptionlog (Joinpoint point,exception ex) {      SYSTEM.OUT.PRINTLN ("Exception Notification" exception information is: "+ex.getmessage ()");             } @AfterReturning (value= "Showlog ()", returning= "result") public void Showafterlog (joinpoint point,object result) { System.out.println ("" Returnreturn value of the notification "method:" +result);      System.out.println (); }}

(2) syntax format for ① pointcut expressions [see 5th AOP Details] Execution ([permission modifier] [return value type] [Simple class name/full class name] [method name] ([parameter list])

See Chapter 5th AOP Details: Demonstration validation
1. Any parameter, any type
2. Any return value
3. Use the @pointcut annotation to unify the statement, and then reference the unified statement in other notices!
Note that: The permission is not supported by the write wildcard, of course, you can write a * represents all the permissions of all return values!


The most detailed pointcut expression:
Execution (public int com.neuedu.aop.target.MathCalculatorImpl.add (int, int))
The most ambiguous pointcut expression: Execution (* * * * (..)) The first * represents the permission and return type but cannot have no permissions but has a return type such as: Execution (* int com.neuedu.aop.target.MathCalculatorImpl.add (int, int)) 7. Unified Sound Explicit Pointcut expression
@Pointcut (value= "Execution (public int com.atguigu.aop.target.EazyImpl.add (int,int))")
public void Mypointcut () {}


8. Details of the notification method
① the method name and argument list for the target method in the notification [1] declares a joinpoint type parameter Jointpoint in the notification method is the pointcut, [2] calls the Joinpoint object getsign Ature () method gets the signature of the target method
[3] Call the Getargs () method of the Joinpoint object to get the actual argument list of the target method
@Before (value= "Showlog ()") public void Showbeginlog (Joinpoint point) {      object[] args = Point.getargs ();//Get Parameters      list<object> aslist = arrays.aslist (args);//Convert to list type      Signature Signature = Point.getsignature ();//Get signature      String name = Signature.getname ();//Get Method name      System.out.println ("Target method Name:" +name+ ", the parameter is:" +aslist);      System.out.println ("log Start");}
② The return value of the method in the return notification [1] adds the returning property in the @AfterReturning annotation [2] declares a formal parameter in the notification method that returns the notification, the parameter name and the value of the returning property are consistent Do not know what type to return, so use the Object type
@AfterReturning (value= "Showlog ()", returning= "result") public void Showafterlog (joinpoint point,object result) {      System.out.println ("Return value of Method:" +result);      System.out.println ("Log normal End");      System.out.println ();}
③ get exception object in exception notification [1] Add throwing property in @AfterThrowing annotation [2] Declare a formal parameter in the notification method of the exception notification, the parameter name and the throwing property value are consistent
@AfterThrowing (value= "Showlog ()", throwing= "ex") public void Showexceptionlog (Joinpoint point,exception ex) {      SYSTEM.OUT.PRINTLN ("Exception information is:" +ex.getmessage ());      SYSTEM.OUT.PRINTLN ("Log Error");}

9. When acquiring a target object based on the interface type, the object actually placed in the IOC container is the proxy object, not the target object itself!


10. Surround Notification: @Around
1. Surround notification requires specifying the Joinpoint sub-interface type Proceedingjoinpoint as a parameter in the parameters of the method
@Around (value= "PointCut ()")
public void Around (Proceedingjoinpoint joinpoint) {
}
2. Surround notice will be the other 4 notifications can be able to do, they have to dry! Note: Be sure to return the method's return value @Around decorated Method!                  itself is equivalent to an agent! But the type of the return value is not known, so use Object
@Around (value= "Execution (public * com.neuedu.aop.rawcaculatorimpl.* (..))") Public Object Showlog (Proceedingjoinpoint point) {      object[] args = Point.getargs ();      list<object> aslist = arrays.aslist (args);      Signature Signature = Point.getsignature ();//Gets the signature      String name = Signature.getname ();      Object Result=null;      try {                 try{                  System.out.println ("Pre-Notification" target method name: "+name+", Parameter: "+aslist");                  result = Point.proceed (args);             } finally{                  System.out.println (the "Post-notification" log eventually returns ");             SYSTEM.OUT.PRINTLN (The return value of the "Return Notification" method: "+result);       } catch (Throwable e) {             System.out.println ("Exception Notification" exception information is: "+e.getmessage ());       }       System.out.println ();       return result;}
11. Priority of Slices
     for the same proxy object, you can have multiple slices together to proxy it.      can be set by @order (VALUE=50) annotations on the slice class, with a lower priority!      No   @Order annotations default Max  
 @Component @aspect@order (value=20) public class Baspect {@Around (value= "      Execution (* com.neuedu.aop.rawcaculatorimpl.* (..)) ")            Public Object Showlog (Proceedingjoinpoint point) {object[] args = Point.getargs ();            list<object> aslist = arrays.aslist (args);            Signature Signature = Point.getsignature ();//Gets the signature String name = Signature.getname ();            Object Result=null;                        try {try{System.out.println ("forward" target method name: "+name+", Parameter: "+aslist");                  result = Point.proceed (args);                  }finally{System.out.println ("POST" log final return ");            } System.out.println (The return value of the "return" method: "+result");            } catch (Throwable e) {System.out.println ("exception" Exception information is: "+e.getmessage ()");            } System.out.println ();      return result; }}

12. Note: The above AOP is implemented by annotations, and AOP can actually be implemented in the way of XML configuration! Erase all annotations
<!--The bean that needs to be loaded into the IOC container is configured--><bean id= "Caculatoraspect" class= "Com.neuedu.aop.CaculatorAspect" ></ Bean><bean id= "Baspect" class= "Com.neuedu.aop.BAspect" ></bean><bean id= "Rawcaculatorimpl" class= "Com.neuedu.aop.RawCaculatorImpl" ></bean><!--configuring AOP, you need to import an AOP namespace--><aop:config> <!-- Declaring Pointcut Expressions--<aop:pointcut expression= "Execution (* com.neuedu.aop.rawcaculatorimpl.* (..))" id= "Mypointcut"/&      Gt <!--Configure the Log slice class, reference the preceding class, control the priority with the Order property--<aop:aspect ref= "Caculatoraspect" order= "> <!--by metho The D attribute specifies the facet method of the slice class, specifying the Pointcut expression by Pointcut-ref--<aop:before method= "Showbeginlog" pointcut-ref= "Mypointcut"/&gt             ; <aop:after method= "Showafterlog" pointcut-ref= "Mypointcut"/> <aop:after-returning method= "ShowReturnL OG "pointcut-ref=" mypointcut "returning=" result "/> <aop:after-throwing method=" Showexceptionlog "Pointcu t-ref= "Mypointcut" throwing= "EX "/> </aop:aspect> <!--Configure the transaction plane class, referencing the preceding class--<aop:aspect ref=" Baspect "order=" > <aop:around method= "Showlog" pointcut-ref= "Mypointcut"/> </aop:aspect></aop:config>

What you need to know is that the management of transactions is very much related to AOP, that is, the bottom of declarative transactions is implemented with AOP!

Spring (iii)--AOP "aspect-oriented programming", notification types and usage, pointcut expressions

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.