Shang Silicon Valley Learning Notes AOP

Shang Silicon Valley AOP

AOP (concept)

1. What is AOP

(1) Aspect oriented programming (aspect oriented programming), AOP can isolate all parts of business logic, so as to reduce the coupling between all parts of business logic, improve the reusability of programs, and improve the efficiency of development.

(2) Popular Description: add new functions to the main functions without modifying the source code

(3) Use the login example to illustrate AOP

AOP (underlying principle)

  1. The underlying AOP uses dynamic agents

    (1) There are two cases of dynamic agents

    In the first case, JDK dynamic proxy is used

    • Create the proxy object of the interface implementation class and enhance the method of the class

    In the second case, CGLIB dynamic proxy is used

    • Create the proxy object of the subclass of the current class and enhance the method of the class
  2. AOP(JDK dynamic agent)

    The first step is to use JDK dynamic Proxy and create objects using Proxy class methods

    (1) Call the newProxyInstance method

    • class Proxy() (check api)

      static Object

      newProxyInstance(ClassLoader loader, class <? > [] interfaces, invocationhandler h) returns an instance of the proxy class of the specified interface, which dispatches the method call to the specified call handler.

    • The first parameter is the class loader

    • The first parameter is the class where the enhancement method is located. The interface implemented by this class supports multiple interfaces

    • The first parameter is to implement this interface InvocationHandler, create proxy objects and write enhanced methods;

    Step 2: write JDK dynamic code

    (1) Create interfaces and define methods

    package com.atguigu.spring5.Dao;
    
    public interface UserDao {
    
        public  int add(int a, int b);
        public String  update(String id);
    }
    
    

    (2) Create interface implementation classes and implement methods

    package com.atguigu.spring5.Dao.impl;
    
    import com.atguigu.spring5.Dao.UserDao;
    
    public class UserDaoImpl implements UserDao {
        @Override
        public int add(int a, int b) {
            return a+b;
        }
    
        @Override
        public String update(String id) {
            return id;
        }
    }
    
    

    (3) Use the Proxy class to create a Proxy object for the interface

    • There are two ways to create proxy objects

      //Anonymous Inner Class 
      Class[] interfaces={UserDao.class};
              Proxy.newProxyInstance(JDKProxy.class.getClassLoader()
                      , interfaces, new InvocationHandler() {
                          @Override
                          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                              return null;
                          }
                      });
      
      //Create object implementation interface
      package com.atguigu.spring5.test;
      
      import com.atguigu.spring5.Dao.UserDao;
      
      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Method;
      import java.lang.reflect.Proxy;
      
      public class JDKProxy {
          public static void main(String[] args) {
              //Create a proxy object that implements the class
              Class[] interfaces={UserDao.class};
              Proxy.newProxyInstance(JDKProxy.class.getClassLoader()
                      , interfaces, new UserDaoProxy() );
          }
      }
      //Create proxy object code
      class UserDaoProxy implements InvocationHandler{
          //Write enhanced logic
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              return null;
          }
      }
      
      
    • code

      package com.atguigu.spring5.test;
      
      import com.atguigu.spring5.Dao.UserDao;
      import com.atguigu.spring5.Dao.impl.UserDaoImpl;
      
      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Method;
      import java.lang.reflect.Proxy;
      import java.util.Arrays;
      
      public class JDKProxy {
          public static void main(String[] args) {
              //Create a proxy object that implements the class
              Class[] interfaces={UserDao.class};
              UserDaoImpl userDao=new UserDaoImpl();
              UserDao dao =(UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader()
                      , interfaces, new UserDaoProxy(userDao));
              int result=dao.add(1,2);
              System.out.println("result:"+result);
          }
      }
      //Create proxy object code
      class UserDaoProxy implements InvocationHandler{
          //1. Who is the proxy object created and who is passed over
          private Object obj;
          //Parameter construction transfer
          public UserDaoProxy(Object obj){
              this.obj=obj;
          }
      
      
      
      
          //Write enhanced logic
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              //Method
              System.out.println("Method..."+method.getName()+":Parameters passed.."+ Arrays.toString(args));
              //Enhanced method execution
              Object res=method.invoke(obj,args);
              //Do a process after the method
              System.out.println("Line after method..."+obj);
      
              return res;
          }
      }
      
      
  3. AOP terminology

    (1) Connection point

    • Class can be enhanced. These methods are connection points

    (2) Entry point

    • The method that is actually really enhanced is called the entry point

    (3) Notification (enhanced):

    • The logical part of the actual enhancement is called notification (enhancement)

    • There are many types of notifications

      (1) Advance notice

      (2) Post notification

      (3) Surround notification

      (4) Exception notification

      (5) Final notice

    (4) Section

    • Apply notifications to pointcut processes

    AOP operation (preparation)

    1. spring frameworks generally implement AOP operations based on AspectJ

      (1) What is AspectJ

      *AspectJ is not a part of Spring. It is an independent AOP framework. Generally, AspectJ and Spring framework are used together for AOP operation

    2. AOP operation based on AspectJ

      (1) Implementation of configuration file based on xml

      (2) Annotation based implementation (use)

    3. Introduce AOP related dependencies into the project

    4. Pointcut expression

      (1) The function of pointcut expression: know which method in which class to enhance

      (2) Syntax structure:

      • execution([permission modifier] [return type] [full path of class] [method name] ([parameter list]))

      • Example 1: com atguigu. dao. add in bookdao class is enhanced

        execution(*com.atguigu.dao.BookDao.add(...) )

      • Example 2: com atguigu. dao. All methods in the bookdao class are enhanced

        execution(com.atguigu.dao.BookDao.(...) )

      • Example 3: com atguigu. All classes and methods in Dao package are enhanced

        execution(* com.atguigu.dao.* .* (...))

    AOP operation (AspectJ annotation)

    1. Create a class and define methods in the class

      package com.atguigu.spring5.aopanno;
      //Enhanced class
      public class User {
          public void  add(){
              System.out.println("add.........");
          }
      
      }
      
      
    2. Create enhanced classes (write your enhanced logic)

      (1) In the enhanced class, create methods so that different methods represent different notification types

      //Enhancement class
      public class UserProxy {
          //Before advice 
          public  void  before(){
              System.out.println("before.......");
          }
      }
      
    3. Configure notifications

      1. (1) In the spring configuration file, turn on annotation scanning

        <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:p="http://www.springframework.org/schema/p"
               xmlns:context="http://www.springframework.org/schema/context"
               xmlns:aop="http://www.springframework.org/schema/aop"
               xsi:schemaLocation=" http://www.springframework.org/schema/beans
                                    http://www.springframework.org/schema/beans/spring-beans.xsd
                                    http://www.springframework.org/schema/aop
                                    http://www.springframework.org/schema/aop/spring-beans.xsd
                                    http://www.springframework.org/schema/context
                                    http://www.springframework.org/schema/context/spring-aop.xsd">
        <!--Enable scanning of annotations-->
            <context:component-scan base-package="com.atguigu.spring5.aopanno"></context:component-scan>
        </beans>
        

        (2) Creating User and UserProxy objects using annotations

        package com.atguigu.spring5.aopanno;
        
        import org.springframework.stereotype.Component;
        
        //Enhanced class
        @Component
        public class User {
            public void  add(){
                System.out.println("add.........");
            }
        
        }
        
        
        package com.atguigu.spring5.aopanno;
        
        import org.springframework.stereotype.Component;
        
        //Enhancement class
        @Component
        public class UserProxy {
            //Before advice 
            public  void  before(){
                System.out.println("before.......");
            }
        }
        
        

        (3) Add the annotation @ Aspect on the enhanced class

        package com.atguigu.spring5.aopanno;
        
        import org.aspectj.lang.annotation.Aspect;
        import org.springframework.stereotype.Component;
        
        //Enhancement class
        @Component
        @Aspect //Generate proxy object
        public class UserProxy {
            //Before advice 
            public  void  before(){
                System.out.println("before.......");
            }
        }
        
        

        (4) Turn on the generation proxy object in the spring configuration file

        <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:p="http://www.springframework.org/schema/p"
               xmlns:context="http://www.springframework.org/schema/context"
               xmlns:aop="http://www.springframework.org/schema/aop"
               xsi:schemaLocation=" http://www.springframework.org/schema/beans
                                    http://www.springframework.org/schema/beans/spring-beans.xsd
                                    http://www.springframework.org/schema/aop
                                    http://www.springframework.org/schema/aop/spring-beans.xsd
                                    http://www.springframework.org/schema/context
                                    http://www.springframework.org/schema/context/spring-aop.xsd">
        <!--Enable scanning of annotations-->
            <context:component-scan base-package="com.atguigu.spring5.aopanno"></context:component-scan>
        <!--open Aspectj Proxy object-->
            <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
        </beans>
        
    4. Configure different types of notifications

      (1) In the enhanced class, add the notification type annotation on the notification method and use the pointcut expression

      package com.atguigu.spring5.aopanno;
      
      import org.aspectj.lang.ProceedingJoinPoint;
      import org.aspectj.lang.annotation.*;
      import org.springframework.stereotype.Component;
      
      
      //Enhancement class
      @Component
      @Aspect //Generate proxy object
      public class UserProxy {
          //Before advice 
          //The before annotation is represented as a pre notification
          @Before(value="execution(* com.atguigu.spring5.aopanno.User.add(..))")
          public  void  before(){
              System.out.println("before.......");
          }
          @After(value="execution(* com.atguigu.spring5.aopanno.User.add(..))")
          public  void  after(){
              System.out.println("after.......");
          }
          @AfterReturning(value="execution(* com.atguigu.spring5.aopanno.User.add(..))")
          public  void  afterReturning(){
              System.out.println("afterReturning.......");
          }
          //Exception notification
          @AfterThrowing(value="execution(* com.atguigu.spring5.aopanno.User.add(..))")
          public  void  afterThrowing(){
              System.out.println("AfterThrowing.......");
          }
          //Surround notification
          @Around(value="execution(* com.atguigu.spring5.aopanno.User.add(..))")
          public  void  around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
              System.out.println("Before surround.......");
              //Enhanced method execution
              proceedingJoinPoint.proceed();
              System.out.println("After surround.......");
          }
      }
      
      
    5. Same pointcut extraction

      package com.atguigu.spring5.aopanno;
      
      import org.aspectj.lang.ProceedingJoinPoint;
      import org.aspectj.lang.annotation.*;
      import org.springframework.stereotype.Component;
      
      
      //Enhancement class
      @Component
      @Aspect //Generate proxy object
      public class UserProxy {
          //Extract from the same pointcut
          @Pointcut(value="execution(* com.atguigu.spring5.aopanno.User.add(..))" )
          public void pointdemo(){
      
          }
      
      
          //Before advice 
          //The before annotation is represented as a pre notification
          @Before(value="pointdemo()")
          public  void  before(){
              System.out.println("before.......");
          }
          @After(value="pointdemo()")
          public  void  after(){
              System.out.println("after.......");
          }
          @AfterReturning(value="pointdemo()")
          public  void  afterReturning(){
              System.out.println("afterReturning.......");
          }
          //Exception notification
          @AfterThrowing(value="pointdemo()")
          public  void  afterThrowing(){
              System.out.println("AfterThrowing.......");
          }
          //Surround notification
          @Around(value="pointdemo()")
          public  void  around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
              System.out.println("Before surround.......");
              //Enhanced method execution
              proceedingJoinPoint.proceed();
              System.out.println("After surround.......");
          }
      }
      
      
    6. There are multiple enhancement classes to enhance the same method. You can set the priority of the enhancement class

      (1) Add the annotation @ order (numeric type value) on the enhanced class. The smaller the numeric type, the higher the priority

      @Component
      @Aspect
      @Order(1)
      public class PersonProxy {
      
    7. Full development annotation

      (1) To create a configuration class, you do not need to create an xml configuration file

      @Configuration
      @ComponentScan(basePackages = {"com.atguigu"})
      @EnableAspectJAutoProxy(proxyTargetClass = true)
      public class configAop {
      

    AOP operation (AspectJ configuration file)

    1. Create two classes, enhanced class and enhanced class, and create methods

    2. Create two class objects in the spring configuration file

      <!--Create objects of two classes-->
          <bean id="book" class="com.atguigu.spring5.aopxml.Book"></bean>
          <bean id="bookProxy" class="com.atguigu.spring5.aopxml.BookProxy"></bean>
      
    3. Configuring pointcuts in the spring configuration file

    <!--to configure aop enhance-->
    <aop:config>
     <!--breakthrough point-->
     <aop:pointcut id="p" expression="execution(*
    com.atguigu.spring5.aopxml.Book.buy(..))"/>
     <!--Configuration section-->
     <aop:aspect ref="bookProxy">
     <!--Enhance the role in specific methods-->
     <aop:before method="before" pointcut-ref="p"/>
     </aop:aspect>
    
    

Keywords: Java Spring AOP

Added by gmiyano on Mon, 07 Feb 2022 10:53:30 +0200