Spring (AOP aspect-oriented)

AOP[Aspect Oriented Programming]

1. What is AOP?
AOP (Aspect Oriented Programing) is called: aspect-oriented programming, which is a programming idea.
Under normal circumstances, there are two kinds of requirements for a system/software:
1. Business requirements: the realization process of a specific business logic function. [Add, delete, modify, query, etc.]
2. System requirements: the functions that help improve the business requirements of the system during the operation of the entire system [performance monitoring, transaction management, security inspection, caching, logging, etc.]
Now we need to complete The action is to quickly implant the system requirements into the necessary business requirements functions where the system requirements need to be used.
At this point, we can quickly embed the system requirement function into the business requirement function through the agent mode.
There are two types of proxy modes: static proxy and dynamic proxy.
Static proxy is composed of father-child mode and brother mode--------traditional vertical inheritance system [a large amount of code repetitive writing]
dynamic proxy is composed of JDK dynamic proxy and CGLIB dynamic proxy--- -Horizontal extraction mechanism
Since JDK dynamic proxy can only generate proxy objects for java objects that have implemented interfaces, it will not be used as an operation method to quickly implant necessary business requirements functions using system requirements functions.
CGLIB dynamic proxy, because it can provide proxy objects for any java class, it was chosen as the underlying implementation of AOP [Aspect Oriented Programming].
CGLIB dynamic proxy is the underlying implementation of Aop.
2. AOP related concepts
joinpoint (connection point): refers to those points that are intercepted. In spring, it refers to a method that can be proxied (enhanced). [Business requirements method in the business class]
poingcut (cutting point): the definition of which connection points are intercepted. In Spring, it refers to methods that really need to be proxied (enhanced).
advice (information/enhancement): Refers to what to do after intercepting the connection point. Those codes (logic) that are really enhanced.
Notification/enhancement is divided into:
pre-notification, post-notification, exception notification, final notification, and surround notification.
Aspect (aspect): It is the combined process of entry point and notification/enhancement.
Introduction (introduction): A special notification without modifying the class code, introduction can dynamically add some methods or fields to the class at runtime.
target: The target object of the code.
weaving: The process of applying enhancements to target objects to create new proxy objects. Spring uses dynamic proxy weaving. AspectJ uses compile-time weaving and class-installation weaving.
Proxy (proxy): After a class is woven and enhanced by AOP, a resulting proxy class is generated.
Insert picture description here

3. The concrete realization of AOP [Aspect Oriented Programming]
Emphasis: Master the writing of pointcut expressions.
Here are some examples of general pointcut expressions.
1. The execution of any public method:
execution (public * (...))
2. The
execution of any method whose name starts with "set": execution ( set * (...))
3. The execution of any method defined by the AccountService interface:
execution (* com.xyz.service.AccountService. (...))
4. The execution of any method defined in the service package:
execution (
com.xyz.service .. (...))
5. In the service package or its sub-packages perform any of the methods defined:
execution (com.xyz.service ... * . (...))
6. the connection at any point in the service package (method execution only in Spring AOP):
WITHIN (com.xyz.service. )
7. Any connection point in the service package or its sub-packages (only method execution in Spring AOP):
within (com.xyz.service...
)
8. Any connection point of the proxy object that implements the AccountService interface (only method execution in Spring AOP):
this (com.xyz.service.AccountService)
'this' is more commonly used in the binding form : -see the notice below Learn how to make the proxy object available in the notification body in the section.
9. Any connection point of the target object that implements the AccountService interface (only method execution in Spring AOP):
target (com.xyz.service.AccountService)
'target' is more commonly used in the binding form : -Please refer to the notice 1 below Learn how to make the target object available in the notification body in this section.
10. Any one only accepts one parameter, and the parameter passed in at runtime is the connection point of the Serializable interface (only method execution in Spring AOP)
args (java.io.Serializable)
'args' is more commonly used in binding forms :- Please refer to the notification section below to learn how to make method parameters available in the notification body.
Please note that the entry point given in the example is different from execution(* *(java.io.Serializable)): The args version only matches when the incoming parameter is Serializable during dynamic operation, and the execution version is declared in the method signature. Matches when a parameter of type Serializable.
11. There is an arbitrary connection point annotated with @Transactional in the target object (only method execution in Spring AOP)
@target (org.springframework.transaction.annotation.Transactional)
'@target' is more commonly used in binding forms:-Please refer to the notification section below to learn how to make the annotation object available in the notification body.
12. Any target object declared type has a connection point of @Transactional annotation (only method execution in Spring AOP):
@within (org.springframework.transaction.annotation.Transactional)
'@within' is more in the binding form Commonly used:-Please refer to the notification section below to learn how to make the annotation object available in the notification body.
13. Any execution method has a connection point of @Transactional annotation (only method execution in Spring AOP)
@annotation (org.springframework.transaction.annotation.Transactional)
'@annotation' is more commonly used in binding forms:- Please refer to the notification section below to learn how to make the annotation object available in the notification body.
14. Any one only accepts one parameter, and the parameter type passed in at runtime has a connection point annotated with @Classified (only method execution in Spring AOP)
@args (com.xyz.security.Classified)
'@args' in It is more commonly used in the binding form:-Please refer to the notification section below to learn how to make the annotation object available in the notification body.
15 Any connection point on the Spring bean named'tradeService' (only method execution in Spring AOP):
bean (tradeService)
16. Any connection point on a Spring bean whose name matches the wildcard expression'*Service' (only method execution in Spring AOP):
bean (*Service)
For example:

com.wangxing.spring.bean
StudentBean
public  void  insertStudent();
public  void  insertStudent(Student);
PersonBean
public  void  insertPerson();
public  void  insertPerson(Student);
public  void  deletePerson(int perid);
execution(com.wangxing.spring.bean.*.*(..))
execution(com.wangxing.spring.bean.StudentBean.*(..))
execution(com.wangxing.spring.bean.*.insert*(..))

1. AOP implementation based on XML file [Spring configuration file]

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>

package com.wangxing.spring.service;
//业务需求类
public class UserService {
    //添加用户信息的业务方法
    public  void  insertUser(){
        System.out.println("添加用户信息的业务方法");
    }
    //修改用户信息的业务方法
    public  void  updateUser(){
        System.out.println("修改用户信息的业务方法");
        //int a=10/0;
    }
    //删除用户信息的业务方法
    public  void  deleteUser(){
        System.out.println("删除用户信息的业务方法");
    }
    //查询用户信息的业务方法
    public  void  selectUser(){
        System.out.println("查询用户信息的业务方法");
    }
}

package com.wangxing.spring.service;
import org.aspectj.lang.ProceedingJoinPoint;
//增强类/通知类
public class MyAvice {
    //系统需求功能实现方法
    public  void  saveLog(){
        System.out.println("记录执行日志");
    }
    //执行环绕通知的系统需求功能实现方法
    public void testAround(ProceedingJoinPoint joinPoint) throws Throwable{
        saveLog();
        joinPoint.proceed(); // 调用真正的业务方法
        saveLog();
    }
}

<?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">
    <!--创建业务类对象-->
    <bean id="userService" class="com.wangxing.spring.service.UserService"></bean>
    <!--创建增强类/通知类对象-->
    <bean id="myAvice" class="com.wangxing.spring.service.MyAvice"></bean>
    <!--1.基于XML文件【Spring配置文件】的AOP实现-->
    <aop:config>
        <!-- 创建切入点 -->
        <aop:pointcut id="point1" expression="execution(* com.wangxing.spring.service.UserService.select*(..))"/>
        <aop:pointcut id="point2" expression="execution(* com.wangxing.spring.service.UserService.deleteUser(..))"/>
        <aop:pointcut id="point3" expression="execution(* com.wangxing.spring.service.UserService.updateUser())"/>
        <aop:pointcut id="point4" expression="execution(* com.wangxing.spring.service.UserService.insertUser())"/>
        <!--配置切面-->
        <aop:aspect ref="myAvice">
            <!--配置通知【切入点执行增强类方法的位置】-->
            <!--前置通知:切入点对应的业务方法执行之前-->
            <aop:before method="saveLog" pointcut-ref="point1"></aop:before>
            <!--后置通知:切入点对应的业务方法执行之后-->
            <aop:after-returning method="saveLog" pointcut-ref="point2"></aop:after-returning>
            <!--异常通知:切入点对应的业务方法执行出现异常时-->
            <aop:after-throwing method="saveLog" pointcut-ref="point3"></aop:after-throwing>
            <!--环绕通知:切入点对应的业务方法执行之前和执行之后都运行-->
            <aop:around method="testAround" pointcut-ref="point4"></aop:around>
            <aop:after method="saveLog" pointcut-ref="point1"></aop:after>
        </aop:aspect>
    </aop:config>
</beans>

2. Implementation of Aop based on annotations

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>

package com.wangxing.spring.service;

import org.springframework.stereotype.Component;

//业务类
@Component("personService")
public class PersonService {
    public  void insertPerson(){
        System.out.println("添加个人信息的业务方法");
    }
    public  void updatePerson(){
        System.out.println("修改个人信息的业务方法");
        //int a=10/0;
    }
    public  void deletePerson(){
        System.out.println("删除个人信息的业务方法");
    }
    public  void selectPerson(){
        System.out.println("查询个人信息的业务方法");
    }
}

package com.wangxing.spring.service;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

//增强类
//@Aspect,表示这个系统需求类是一个切面
@Component
@Aspect
public class MyAvice {
    //系统需求功能实现方法
    //@Before("execution(* com.wangxing.spring.service.PersonService.selectPerson())")
    //@AfterReturning("execution(* com.wangxing.spring.service.PersonService.deletePerson())")
    //@AfterThrowing("execution(* com.wangxing.spring.service.PersonService.updatePerson())")
    @After("execution(* com.wangxing.spring.service.PersonService.updatePerson())")
    public  void  saveLog(){
        System.out.println("记录执行日志");
    }
    //执行环绕通知的系统需求功能实现方法
    @Around("execution(* com.wangxing.spring.service.PersonService.insertPerson())")
    public void testAround(ProceedingJoinPoint joinPoint) throws Throwable{
        saveLog();
        joinPoint.proceed(); // 调用真正的业务方法
        saveLog();
    }
}

<?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: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/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--使用context命名空间,通知spring扫描指定目录,进行注解的解析-->
    <context:component-scan base-package="com.wangxing.spring.service"></context:component-scan>
    <!--开启aop注解-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

Guess you like

Origin blog.csdn.net/guoguo0717/article/details/109892356