AOP Face Oriented Programming

Posted by khendar on Wed, 29 May 2019 18:27:59 +0200

1. Generation of Aspect Oriented Programming Requirements

    1. Code clutter: With more and more non-business requirements (logs, validation, etc.) added, the original business approach has expanded dramatically.Each approach must take into account multiple other concerns while handling core logic.
    2. Code Distribution: For example, log requirements, the same log code has to be repeated multiple times in multiple modules (methods) to meet this single requirement.If log requirements change, all modules must be modified.

2. Realizing Face-Oriented Programming

    1. Classes that need to implement AOP are injected into the Spring container, for example:
       1 package com.neuedu.aop;
       2 
       3 import org.springframework.stereotype.Component;
       4 
       5 @Component
       6 public class RawCaculator implements MathCaculator{
       7 
       8     @Override
       9     public int add(int i, int j) {
      10         int rs=i+j;
      11         System.out.println(i+"+"+j+"="+rs);
      12         return rs;
      13     }
      14 
      15     @Override
      16     public int sub(int i, int j) {
      17         int rs=i-j;
      18         System.out.println(i+"-"+j+"="+rs);
      19         return rs;
      20     }
      21 
      22     @Override
      23     public int mul(int i, int j) {
      24         int rs=i*j;
      25         System.out.println(i+"*"+j+"="+rs);
      26         return rs;
      27     }
      28 
      29     @Override
      30     public int div(int i, int j) {
      31         int rs=i/j;
      32         System.out.println(i+"/"+j+"="+rs);
      33         return rs;
      34     }
      35 
      36 }
      Class of calculation methods to implement AOP

 

  • Implement Face Class
    1. Implement a facet class using pre-notification, post-notification, return notification, exception notification, and inject it into the Spring container
       1 package com.neuedu.aop;
       2 
       3 import static org.hamcrest.CoreMatchers.nullValue;
       4 
       5 import java.util.Arrays;
       6 import java.util.List;
       7 
       8 import org.aspectj.lang.JoinPoint;
       9 import org.aspectj.lang.ProceedingJoinPoint;
      10 import org.aspectj.lang.Signature;
      11 import org.aspectj.lang.annotation.After;
      12 import org.aspectj.lang.annotation.AfterReturning;
      13 import org.aspectj.lang.annotation.AfterThrowing;
      14 import org.aspectj.lang.annotation.Around;
      15 import org.aspectj.lang.annotation.Aspect;
      16 import org.aspectj.lang.annotation.Before;
      17 import org.springframework.core.annotation.Order;
      18 import org.springframework.stereotype.Component;
      19 
      20 @Component
      21 //@Aspect Indicates that the current class is a tangent class
      22 @Aspect
      23 //@Order Represents the order in which the facets are executed. value The smaller the value, the higher the priority
      24 @Order(value=50)
      25 public class CaculatorAspect {
      26         @Before(value = "execution(public int com.neuedu.aop.RawCaculator.*(int, int))")
      27         public void showBeginLog(JoinPoint point){
      28             //System.out.println("[Log [Pre-notification]");
      29             //Get a list of parameters:
      30             Object[] args = point.getArgs();
      31             List<Object> asList = Arrays.asList(args);
      32             //Get the method name:
      33             Signature signature = point.getSignature();
      34             String name = signature.getName();
      35             System.out.println("[Log [Pre-notification] Target method name is:"+name+"The parameters are:"+asList);
      36         }
      37         @AfterThrowing(value = "execution(public int com.neuedu.aop.RawCaculator.*(..))" ,throwing="ex")
      38         public void showThrowing(JoinPoint point,Exception ex){
      39             //System.out.println("[Log [Exception Notification]");
      40             System.out.println("[Log [Exception Notification] Exception information:"+ex);
      41         }
      42         @After(value = "execution(public int com.neuedu.aop.RawCaculator.*(..))")
      43         public void showAfter(){
      44             System.out.println("[Log [Post Notification]");
      45         }
      46         @AfterReturning(value = "execution(* * .*(..))",returning="result")
      47         public void showAfterReturning(JoinPoint point,Object result){
      48             //System.out.println("[Log [Return Notification]");
      49             System.out.println("[Log [Return Notification] The return value of the target method is"+result);
      50         }
      51     }

       

  •  

    Code labeled with a yellow background is declared notifications, including notification types and entry point expressions, which are described below with the entry point expression at the end

    Before Pre-Notification: Notification to be executed before method execution

    After Post Notification: Post Notification is performed after the connection point has completed, that is, when the connection point returns a result or throws an exception

    Back to notification at @AfterReturning:

    @AfterThrowing exception notification: only perform exception notifications when an exception is thrown by a connection point.

               

    2. Use wrapping notifications to implement facet classes and inject them into the Spring container

     1   package com.neuedu.aop;
     2 
     3   import java.util.Arrays;
     4   import java.util.List;
     5 
     6   import org.aspectj.lang.ProceedingJoinPoint;
     7   import org.aspectj.lang.Signature;
     8   import org.aspectj.lang.annotation.Around;
     9   import org.aspectj.lang.annotation.Aspect;
    10   import org.springframework.core.annotation.Order;
    11   import org.springframework.stereotype.Component;
    12 
    13   @Component
    14   //@Aspect Indicates that the current class is a tangent class
    15   @Aspect
    16   @Order(value=40)
    17     public class secondAspect {
    18       @Around(value = "execution(* * .*(..))")
    19       public Object Around(ProceedingJoinPoint point){
    20           Object result=null;
    21           Object[] args = point.getArgs();
    22           List<Object> asList = Arrays.asList(args);
    23           Signature signature = point.getSignature();
    24           String name = signature.getName();
    25           try{
    26               System.out.println("[Transaction Log [Pre-notification] The target method is named:"+name+"The parameters are:"+asList);
    27               try {
    28                   result=point.proceed(args);
    29                 } finally{
    30                     System.out.println("[Things Log [Post Notification]");
    31                 }    
    32               System.out.println("[Transaction Log [Return Notification] The return value of the target method is"+result);    
    33           }catch (Throwable e) {
    34               System.out.println("[Event Log [Exception Notification] Exception information:"+e);
    35           }
    36           return result;
    37       }
    38   }

     

    Around notifications:

         

    3. Implement test classes

     

    package junit.test;
    
    import static org.junit.Assert.*;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.neuedu.aop.MathCaculator;
    import com.neuedu.aop.RawCaculator;
    
    public class TestCaculator {
    
        @Test
        public void test() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
            //MathCaculator bean = ioc.getBean(RawCaculator.class);   Not available (representing different types of classes)
            //rawCaculator Even when using annotations id;again xml In the configuration file id
            MathCaculator bean = (MathCaculator) ioc.getBean("rawCaculator");
            bean.add(10, 5);
            System.out.println();
            bean.sub(14, 5);
            System.out.println();
            bean.mul(8, 7);
            System.out.println();
            bean.div(10, 0);
        }
    
    }
    Test Class

     

      

    3. About expression of entry point

    1. Role:

    Locate one or more specific connection points by expression.

    2. Grammatical details:

    1) Syntax format of entry point expression: execution([permission modifier] [return value type] [simple class name/full class name] [method name] ([parameter list]))

    2) Examples:

              

    Expression

    execution(* com.atguigu.spring.ArithmeticCalculator.*(..))

    Meaning

    All methods declared in the ArithmeticCalculator interface.

    The first'*'represents any modifier and any return value.

    The second'*'represents any method.

    '. 'matches any number of parameters of any type.

    If the target class, interface, and facet class are in the same package, the package name can be omitted.

     

    Expression

    execution(public * ArithmeticCalculator.*(..))

    Meaning

    All public methods of the ArithmeticCalculator interface

     

    Expression

    execution(public double ArithmeticCalculator.*(..))

    Meaning

    Methods for returning double-type values in the ArithmeticCalculator interface

     

    Expression

    execution(public double ArithmeticCalculator.*(double, ..))

    Meaning

    The first parameter is a method of type double.

    '. 'matches any number of parameters of any type.

     

    Expression

    execution(public double ArithmeticCalculator.*(double, double))

    Meaning

    Method with parameter type double and double

    3. Reuse entry points:

          1)

    2) Sample code:

     1   @Component
     2   //@Aspect Indicates that the current class is a tangent class
     3   @Aspect
     4   //@Order Represents the order in which the facets are executed. value The smaller the value, the higher the priority
     5   @Order(value=50)
     6   public class CaculatorAspect {
     7           //Reuse entry point
     8           @Pointcut("execution(* * .*(..))")
     9           private void LoggingOperation(){
    10               
    11           }
    12           @Before(value = "LoggingOperation()")
    13           public void showBeginLog(JoinPoint point){
    14               //Get a list of parameters:
    15               Object[] args = point.getArgs();
    16               List<Object> asList = Arrays.asList(args);
    17               //Get the method name:
    18               Signature signature = point.getSignature();
    19               String name = signature.getName();
    20               System.out.println("[Log [Pre-notification] Target method name is:"+name+"The parameters are:"+asList);
    21           }
    22           @AfterThrowing(value = "LoggingOperation()" ,throwing="ex")
    23           public void showThrowing(JoinPoint point,Exception ex){
    24               System.out.println("[Log [Exception Notification] Exception information:"+ex);
    25           }
    26           @After(value = "LoggingOperation()")
    27           public void showAfter(){
    28               System.out.println("[Log [Post Notification]");
    29           }
    30           @AfterReturning(value = "LoggingOperation()",returning="result")
    31           public void showAfterReturning(JoinPoint point,Object result){
    32               System.out.println("[Log [Return Notification] The return value of the target method is"+result);
    33           }
    34       }

     

     

     



    Topics: Java Spring Junit Programming