AOP

Time:2021-11-29

The role of AOP in spring

It is learned from the previous section that the underlying layer of AOP is throughDynamic agentIf you want to use AOP for weaving, you need to import dependencies.
AOP has many functions, provides declarative transactions, and allows users to customize aspects

  • Crosscutting concerns: methods or functions that span multiple modules of an application. That is, the part that has nothing to do with our business logic, but we need to focus on is crosscutting concerns. Such as logging, security, caching, transactions, etc
  • Aspect: a special object whose crosscutting concerns are modularized. That is, it is a class.
  • Advice: work that must be completed in all aspects. That is, it is a method in a class.
  • Target: the notified object.
  • Proxy: an object created after notification is applied to the target object.
  • Pointcut: the definition of the “place” where the aspect notification is executed.
  • Uointpoint: the execution point that matches the pointcut.
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.4</version>
    </dependency>

    There are three ways to implement AOP:

  • Method 1: use the spring API interface [mainly the spring interface implementation]
  • Method 2: user defined class implementation [mainly section definition]
  • Method 3: implement with annotations

prepare

First, there are several methods in the service layer and several methods in the userservice interface

public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void search();
}

Implement class inheritance interface and implementation method

public class UserServiceImpl implements UserService {

    public void add() {
        System.out.println ("added a user");
    }

    public void delete() {
        System.out.println ("a user was deleted");

    }

    public void update() {
        System.out.println ("a user has been updated");

    }

    public void search() {
        System.out.println ("a user was queried");

    }
}

Method 1: use the spring API interface [mainly the spring interface implementation]

Add log printing before and after all methods. First, add log printing before method execution, inherit the methodbeforeadvice interface, and implement the before method.

public class Log implements MethodBeforeAdvice {

    //Method: the method of the target object to execute
    //Objects: parameters
    //o: Target object
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System. Out. Println (o.getclass(). Getname() + "+ method. Getname() +" executed ");
    }
}

Add log printing after method

public class AfterLog implements AfterReturningAdvice {

    //returnValue; Return value
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System. Out. Println ("the" + method. Getname() + "method is executed, and the return result is:" + returnValue ");
    }
}

Then configure the ApplicationContext. XML 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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

<!-- Register beans -- >
<bean id="userService" class="com.hudu.service.UserServiceImpl"/>
<bean id="log" class="com.hudu.log.Log"/>
<bean id="afterLog" class="com.hudu.log.AfterLog"/>

<!-- Method 1: use the native spring API interface -- >
<!-- Configuring AOP: constraints to import AOP -- >
<aop:config>
  <!-- Pointcut: expression: expression execution (where to execute, * (return type, * indicates all types) class name method name parameter) - >
  <aop:pointcut id="pointcut" expression="execution(* com.hudu.service.UserServiceImpl.*(..))"/>

  <!-- Perform surround enhancement -- >
  <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
 <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>

</beans>

User defined class implementation [mainly section definition]

First, customize a class diypointcut

public class DiyPointCut {

    public void before() {
        System. Out. Println ("=====================") before method execution;
    }

    public void after() {
        System. Out. Println ("=====================") after the method is executed;
    }
}

Configuration XML file

<!-- Method 2: user defined class -- >
    <bean id="diy" class="com.hudu.diy.DiyPointCut"/>

    <aop:config>
        <!-- Custom facet, ref class to reference -- >
        <aop:aspect ref="diy">
            <!-- Entry point -- >
            <aop:pointcut id="point" expression="execution(* com.hudu.service.UserServiceImpl.*(..))"/>
            <!-- Notification -- >
            <aop:before method="before" pointcut-ref="point"/>
            <aop:after method="after" pointcut-ref="point"/>
        </aop:aspect>
    </aop:config>

Using annotations

Define a class

@Aspect // indicates that this class is an aspect
public class AnnotationPointCut {

    @Before("execution(* com.hudu.service.UserServiceImpl.*(..))")
    public void before() {
        System. Out. Println ("***************** before method execution");
    }

    @After("execution(* com.hudu.service.UserServiceImpl.*(..))")
    public void after() {
        System. Out. Println ("=====================") after the method is executed;
    }

    //In surround enhancement, we can give a parameter to represent the pointcut we want to get processing
    @Around("execution(* com.hudu.service.UserServiceImpl.*(..))")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println ("before surround");

        Signature signature = joinPoint.getSignature();// Get signature
        System.out.println("signature:"+signature);
        //Execution method
        Object proceed = joinPoint.proceed();

        System.out.println ("after surround");
        System.out.println(proceed);
    }
}

Configuration XML file

<!-- Method 3: use annotation -- >
    <bean id="annotationPointCut" class="com.hudu.diy.AnnotationPointCut"/>
    <!-- Enable annotation support JDK (default) cglib (proxy target class = "true") -- >
    <aop:aspectj-autoproxy proxy-target-class="false"/>

This work adoptsCC agreement, reprint must indicate the author and the link to this article