AOP aspect oriented programming for Spring basic learning

preface:

Hello, guys, I'm running snail rz. Of course, you can call me snail Jun. I'm a rookie who has studied Java for more than half a year. At the same time, I also have a great dream, that is, to become an excellent Java Architect one day.
This Spring basic learning series is used to record the whole process of learning the basic knowledge of Spring framework (this series is written with reference to the latest Spring 5 tutorial of crazy God in station B. because it was sorted out before, but it was not released at that time, there may be errors in some places. I hope you can correct them in time!)
After that, I will update this series at a faster rate day by day. If you haven't learned the spring 5 framework, you can learn from my blog; Of course, the little friends who have studied can also review the basics with me.
Finally, I hope I can make progress with you! Come on! Boys!
No more nonsense. Let's start today's learning content. Today we come to the tenth stop of Spring basic learning: AOP aspect oriented programming!

11.AOP aspect oriented programming

11.1 AOP overview

11.1.1 what is AOP?

  • AOP (Aspect Oriented Programming): a technology of Aspect Oriented Programming, which realizes the unified maintenance of program functions through precompiled mode and runtime dynamic agent
  • AOP is the continuation of OOP, a hot spot in software development, an important content in Spring framework, and a derivative paradigm of functional programming

11.1.2 advantages of AOP

  • AOP can isolate all parts of business logic, so that business personnel can concentrate on the processing of business logic
  • Reduce the coupling degree between various parts of business logic and improve the reusability of programs
  • Improve the maintainability of the system and improve the efficiency of development

AOP aspect oriented programming structure diagram:

11.2 role of AOP in Spring

11.2.1 AOP related concepts

Provide declarative transactions: that is, allow users to customize aspects

  • Crosscutting concerns: methods or functions that span multiple modules of an application (i.e., those that have nothing to do with business logic but need attention), which are crosscutting concerns (such as log management, permission control, transaction processing, exception handling, etc.)
  • Aspect: a special object whose crosscutting concerns are modularized (that is, the combination of pointcuts and notifications), that is, it is a class (such as log class)
  • Advice: the work that must be completed in the aspect (that is, the enhanced content of the pointcut). It is a method in the class (the method in the Log class Log, such as pre -, post -, and surround notifications)
  • Pointcut: refers to the jointpoints to be intercepted, that is, the intercepted connection point (which can be understood as the definition of the "place" where the aspect notification is executed)
  • Jointpoint: refers to the intercepted points. In Spring, dynamic proxy can be used to intercept the methods of the target class (i.e. the execution point matching the pointcut)
  • Target: refers to the target object of the agent (that is, the notified object)
  • Proxy: refers to the generated proxy object (that is, the object created after the notification is applied to the target object)
  • Weaving: refers to the process of applying enhanced code to the target and generating proxy objects

11.2.2 AOP implementation structure diagram

11.2.3 Advice in spring AOP

In Spring AOP, crosscutting logic is defined through Advice, and Spring supports Advice of type 5

Notification typeeffectImplementation interfaceapplication
Before advice Implement enhancements before the implementation of the target method,org.springframework.aop.MethodBeforeAdviceCan be applied to rights management
Post notificationImplement enhancements after target method executionorg.springframework.aop.AfterReturningAdviceYou can use functions such as closing streams, uploading files, deleting temporary files, etc
Around Advice Implement enhancements before and after the implementation of the target methodorg.aopalliance.intercept.MethodInterceptorIt can be applied to log, transaction management and other functions
Exception throw notificationExecute notification after the method throws an exceptionorg.springframework.aop.ThrowsAdviceIt can be used to handle exceptions, record logs and other functions
Introduction noticeAdd some new methods and properties to the target classorg.springframework.aop.IntroductionInterceptorCan be applied to old version programs (enhanced classes)

That is, AOP adds new functions without changing the original code

11.3 using Spring to implement AOP

11.3.1 to use AOP weaving, you need to import a dependency package

 <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
        </dependency>
    </dependencies>
  • Method 1: use Spring API interface [mainly implemented by Spring API interface]
  • Method 2: Customize to implement AOP [mainly section definition]

11.3.2 using Spring API interface

1. Create a Log entity class

//Log entity class that implements the pre notification interface
public class Log implements MethodBeforeAdvice {

    /**
     * Pre notification method
     * @param method: Method of the target object to execute
     * @param args: parameter
     * @param target: Target reading and writing
     */
    public void before(Method method, Object[] args, Object target) throws Throwable {
    
        System.out.println(target.getClass().getName()+"of"+method.getName()+"Executed");
        
    }
    
}

2. Create AfterLog entity class

// AfterLog entity class implementing post notification interface
public class AfterLog implements AfterReturningAdvice {

    // returnValue: return value
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("Yes"+method.getName()+"Method, the return result is:"+returnValue);
    }
    
}

3. Create UserService interface

// Create user service interface (Abstract role)
public interface UserService {

    // Define addition, deletion, modification and query methods
    public void add();
    
    public void delete();
    
    public void update();
    
    public void query();
    
}

4. Create UserService interface implementation class

// Implementation class of user service interface (real role)
public class UserServiceImpl implements UserService {

    public void add() {
        System.out.println("Add a user");
    }
    
    public void delete() {
        System.out.println("Delete a user");
    }
    
    public void update() {
        System.out.println("Modify and add a user");
    }
    
    public void query() {
        System.out.println("Query a user");
    }
    
}

5.applicationContext.xml 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: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-aop.xsd">
    
    <!-- Register target classes and facets, etc bean object -->
    <!-- Target class -->
    <bean id="userService" class="com.kuang.service.UserServiceImpl"></bean>
    <!-- section -->
    <bean id="log" class="com.kuang.log.Log"></bean>
    <bean id="afterLog" class="com.kuang.log.AfterLog"></bean>
    
    <!-- Method 1: use native Spring API Interface -->
    <!-- to configure aop: Import required aop Constraints of -->
    <aop:config>
        <!-- Configure pointcuts to inform you of the last enhancement methods -->
        <!-- pointcut It refers to the intercepted connection point, that is, the execution point of aspect notification -->
        <!-- expression: Using slice expressions, enhance com.kuang.service.UserServiceImpl All methods of all types under the package -->
        <aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
        <!-- Associated notification Advice And entry points pointcut -->
        <!-- Before advice  -->
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <!-- Post notification -->
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    </aop:config>
    
</beans>

6. Create test class

public class MyTest {
    public static void main(String[] args) {
    
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        // Dynamic agents are interfaces
        UserService userService = (UserService) context.getBean("userService");
        userService.add();
    }
    
}

7. Test results

11.3.3 customize to implement AOP

1. User defined section class

// Customized aspect class: there can be multiple notification Advice (enhanced method content)
public class DiyPointCut {
    
    // Before advice 
    public void before() {
        System.out.println("======Before method execution======");
    }
    
    // Post notification
    public void after() {
        System.out.println("======After method execution======");
    }
    
}

2. Create UserService interface

Same as UserService interface in 11.3.2

3. Create UserService interface implementation class

The same as the UserService interface implementation class in 11.3.2

4.xml 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: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-aop.xsd">
    
    <!-- Register target class and facet bean information -->
    <!-- Target class -->
    <bean id="userService" class="com.kuang.service.UserServiceImpl"></bean>
    
    <!-- Method 2: user defined class -->
   <!-- Aspect: in fact, it is a special object modularized(It's actually a class) -->
    <bean id="diy" class="com.kuang.diy.DiyPointCut"/>
     <!-- to configure aop -->
    <aop:config>
        <!-- Introduce a custom section, ref Is the class to reference -->
        <aop:aspect ref="diy">
             <!-- Configure pointcuts to inform you of the last enhancement methods -->
            <!-- pointcut: It refers to the intercepted connection point, that is, the place where the aspect notification is executed -->
            <!-- expression: Using slice expressions, enhance com.kuang.service Specified class under UserServiceImpl All methods of all types -->
            <aop:pointcut id="point" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
                <!-- enhance com.kuang.service Package and all methods of all types of all classes under its sub package -->
<!--            <aop:pointcut id="point" expression="execution(* com.kuang.service..*.*(..))"/>-->
            <!-- Associated notification Advice And entry points pointCut -->
            <!-- Advice: It refers to the work that must be completed in the aspect, and the enhanced content of the entry point(It's actually a method of a class) -->
            <!-- Before advice  -->
            <aop:before method="before" pointcut-ref="point"/>
            <!-- Post notification -->
            <aop:after method="after" pointcut-ref="point"/>
        </aop:aspect>
    </aop:config>
    
</beans>

5. Create test method

  • The same as the test method in 11.3.2

6. Test results

11.3.4 Aspectj pointcut syntax definition

Define pointcut expressions: for example, execution(* com.example.service.impl... *. * (...))

execution() is a commonly used pointcut function. Its syntax is: the whole expression can be divided into five parts

  • execution(): expression body

  • The first * indicates the return type, and the * indicates all types

  • Package name: indicates the name of the package to be intercepted. The following two periods represent the current package and all sub packages of the current package, and the methods of all classes under com.example.service.impl package and descendant package

  • The second * sign: indicates the class name, and the * sign indicates all classes

  • *(...): the last asterisk represents the method name, the * sign represents all methods, the following parentheses represent the method parameters, and the two periods represent any parameters

Summary:

In short, the function of this expression is to enhance all methods of all types of all classes under the package and its sub packages

11.3.5 implementing AOP with annotations

1. Create AnnotationPointCut entity class

// Method 3: implement AOP by annotation
@Aspect
// Annotation this class is a facet
public class AnnotationPointCut {
    
    // Pre notification (pointcut expression)
    @Before("execution(* com.kuang.service.UserServiceImpl.*(..))")
    public void before() {
        System.out.println("====Before method execution====");
    }
    
    // Post notification (pointcut expression)
    @After("execution(* com.kuang.service.UserServiceImpl.*(..))")
    public void after() {
        System.out.println("====After method execution=====");
    }
    
    // Around Advice 
    @Around("execution(* com.kuang.service.UserServiceImpl.*(..))")
    // In surround enhancement, we can give a parameter representing the point where we want to get the processing pointcut
    public void around(ProceedingJoinPoint jp) throws Throwable { // The parameters in the wrap method are connection points
        System.out.println("=====Surround front=====");
        Signature signature = jp.getSignature(); // Get signature
        System.out.println("Signed by:"+signature);
        Object proceed = jp.proceed(); // Execution method
        System.out.println("=====After surround=====");
        System.out.println(proceed);
    }
    
}

2. Create UserService interface

  • Same as 11.3.2 userservice interface

3. Create UserService interface implementation class

  • Same as 11.3.3 userserviceimpl implementation class

4.applicationContext3.xml 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: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-aop.xsd">
    
    <!-- Method 3: using annotations AOP -->
    <!--Aspect: in fact, it is a special object modularized(It's actually a class)-->
    <bean id="annotationPointCut" class="com.kuang.diy.AnnotationPointCut"/>
    <!-- Enable annotation support JDK(default proxy-target-class="true") cglib(proxy-target-class="true") -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
    
</beans>

5. Create test class

public class MyTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext3.xml");
        // Note: dynamic agents are interfaces
        UserService userService = (UserService) context.getBean("userService");
        userService.add();
    }
    
}

6. Test results

Well, today's learning about AOP aspect oriented programming is over. Welcome to study and discuss actively. If you like, you can pay attention to Mr. snail. By the way, we'll see you next time. Bye!

Reference video link: https://www.bilibili.com/video/BV1WE411d7Dv([crazy God says Java] the latest tutorial of spring 5, the IDEA version is easy to understand)

Tags: Java AOP Dynamic Proxy IDEA

Posted on Sat, 16 Oct 2021 13:07:39 -0400 by scratchwax2003