Spring AOP quick start

1, AOP configuration in Spring

In Spring's AOP configuration, like IoC configuration, three types of configuration are supported.
The first type: using XML configuration;
The second type: using XML + annotation combination configuration;
The third category: use pure annotation configuration.

2, XML configuration schema

1. Import dependency

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.2.9.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.6</version>
</dependency>

2. aop core configuration

<!-- 
    Spring be based on XML of AOP Preparation for configuration:
    stay spring Add to the configuration file aop Constraints of 
    xmlns:aop="http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop
    https://www.springframework.org/schema/aop/spring-aop.xsd"
    
    Spring be based on XML of AOP Configuration steps:
        First step: Notify Bean hand Spring Administration 
        Step 2: use aop:config start aop Configuration of 
        Step 3: use aop:aspect Configure section 
        Step 4: Configure the type of notification using the corresponding label
            Pre notification is adopted for incoming cases, and the label is aop:before 
 -->
<!-- Notify bean hand spring To manage -->
<bean id="logUtil" class="com.lagou.utils.LogUtil"></bean>
<!--start aop Configuration of-->
<aop:config>
    <!--Configure section-->
    <aop:aspect id="logAdvice" ref="logUtil">
        <!--Configure pre notification-->
        <aop:before method="printLog" pointcut="execution( * 
                ....TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Account))">
        </aop:before>
    </aop:aspect>
</aop:config>

3. Core configuration details

1) About pointcut expressions

The above configuration implements the enhancement of the updateAccountByCardNo method of TransferServiceImpl. Before its execution, the log recording statement is output.
Here, we come into contact with a relatively unfamiliar name: pointcut expression. What does it do? Let's look down.

  • Concept and function

Pointcut expressions, also known as AspectJ pointcut expressions, refer to strings that follow a specific syntax structure and are used to enhance join points that conform to the syntax format. It is part of the AspectJ expression.

  • About AspectJ

AspectJ is an AOP framework based on Java language. Since version 2.0, Spring framework has integrated the part of pointcut expression in AspectJ framework and began to support AspectJ pointcut expression.

  • Example of pointcut expression usage
Fully qualified method name: access modifier return value package name.Package name.Package name.Class name.Method name(parameter list) 
Full matching method:
public void com.lagou.service.impl.TransferServiceImpl
        .updateAccountByCardNo(com.lagou.pojo.Account)

Access modifiers can be omitted:
void com.lagou.service.impl.TransferServiceImpl
        .updateAccountByCardNo(com.lagou.pojo.Account)

The return value can be used *,Represents any return value:
* com.lagou.service.impl.TransferServiceImpl
        .updateAccountByCardNo(com.lagou.pojo.Account)

Package name can be used . Represents any package, but there are several levels of packages, which must be written:
* ....TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Account)

Package name can be used .. Represents the current package and its sub packages:
* ..TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Account)

Class name and method name can be used . Represents any class, any method:
* ...(com.lagou.pojo.Account)

Parameter list, you can use specific types:
Basic type direct write type name: int
 Reference types must write fully qualified class names: java.lang.String

The parameter list can be used * ,Represents any parameter type, but must have parameters:
* *..*.*(*)
The parameter list can be used..,Indicates whether there are parameters or not. Parameters can be of any type:
* *..*.*(..)
Full pass configuration mode:
* *..*.*(..)

2) Change the configuration of agent mode

When Spring chooses to create a proxy object, it will select it according to the actual situation of the proxy object.
If the proxy object implements the interface, the dynamic proxy based on the interface is adopted.
When the proxy object does not implement any interface, Spring will automatically switch to the subclass based dynamic proxy mode.

However, we all know that no matter whether the proxy object implements the interface or not, as long as the class is not final modified, the proxy object can be created in the way provided by cglib.
Therefore, Spring also takes this situation into account and provides a configuration method to enforce the use of subclass based dynamic proxy (i.e. cglib). There are two configuration methods:

  • Configuring using the aop:config tag
<aop:config proxy-target-class="true" />
  • Configure with AOP: AspectJ AutoProxy tag
<!-- This label is based on XML And annotation combination configuration AOP A mandatory label for when, indicating Spring Enable annotation configuration AOP Support of -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>

3) Five notification types

  • Before advice

Configuration method:
aop:before tag

<!--
    effect:
        Used to configure pre notification.
    Occurrence position: 
        It can only appear in aop:aspect Inside the label.
    attribute:
        method: The method name used to specify the pre notification;
        pointcut: Expressions used to specify pointcuts; 
        pointcut-ref: A reference that specifies the pointcut expression.
-->
<aop:before method="printLog" pointcut-ref="pointcut1">
</aop:before>

Execution time:
Pre notification is always executed before the pointcut method (business core method) is executed.
Details:
Pre notification can obtain and enhance the parameters of pointcut methods.

  • Notify on normal execution

Configuration method:
AOP: after returning tag

<!--
    effect: 
        Used to configure notifications on normal execution.
    Occurrence position: 
        It can only appear in aop:aspect Inside the label.
    attribute: 
        method: Method name used to specify post notification;
        pointcut: Expressions used to specify pointcuts;
        pointcut-ref: A reference that specifies the pointcut expression.
-->
<aop:after-returning method="afterReturningPrintLog" pointcut-ref="pt1">
</aop:after-returning>
  • Exception notification

Configuration mode:
AOP: after throwing tag

<!--
    effect: 
        Used to configure exception notification.
    Occurrence position: 
        It can only appear in aop:aspect Inside the label.
    attribute: 
        method: Method name used to specify exception notification;
        pointcut: Expressions used to specify pointcuts; 
        pointcut-ref: A reference that specifies the pointcut expression.
-->
<aop:after-throwing method="afterThrowingPrintLog" pointcut-ref="pt1">
</aop:after-throwing>

Execution time:
The execution time of exception notification is after the execution of the pointcut method (business core method) generates an exception, the exception notification is executed.
If the pointcut method execution does not generate an exception, the exception notification is not executed.
Details:
Exception notification can not only obtain the parameters of pointcut method execution, but also obtain the exception information generated by pointcut method execution.

  • Final notice

Configuration method:
aop:after tag

<!--
    effect: 
        Used to specify the final notification.
    Location of occurrence: 
        It can only appear in aop:aspect Inside the label.
    attribute: 
        method: The name of the method used to specify the final notification;
        pointcut: Expressions used to specify pointcuts;
        pointcut-ref: A reference that specifies the pointcut expression.
-->
<aop:after method="afterPrintLog" pointcut-ref="pt1">
</aop:after>

Execution time:
The execution time of the final notification is after the execution of the pointcut method (business core method) and before the pointcut method returns.
In other words, the pointcut method executes before it returns, whether or not it generates an exception.
Details:
When the final notification is executed, you can get the parameters of the notification method. At the same time, it can do some cleaning operations.

  • Around Advice

Configuration method:
aop:around tag

<!--
    effect: 
        Used to configure surround notifications.
    Location of occurrence: 
        It can only appear in aop:aspect Inside the label.
    attribute: 
        method: The method name used to specify the surround notification;
        pointcut: Expressions used to specify pointcuts;
        pointcut-ref: A reference that specifies the pointcut expression.
-->
<aop:around method="aroundPrintLog" pointcut-ref="pt1">
</aop:around>

4) Special note

Surround notification is a special notification different from the previous four notification types.
The first four notifications (pre, post, exception, and final) are notification types that specify when to enhance.
Surround notification is a notification type provided by the Spring framework that can control when enhanced code is executed through coding.
With the help of the ProceedingJoinPoint interface and its implementation class, it can manually trigger the call of pointcut methods.

3, XML + annotation schema

1. Enable Spring's support for annotation AOP in XML

<!-- open spring Comment on aop Support of -->
<aop:aspectj-autoproxy />

2. Example

/**
 * Simulation log
 * @author jason559
 */
@Component("logUtil")
@Aspect
public class LogUtil {

    /**
     * We have used a common pointcut expression in xml for multiple aspects, so how to use it in annotations?
     * Step 1: write a method;
     * Step 2: use @ Pointcut annotation in the method;
     * Step 3: provide a pointcut expression for the value attribute of the annotation;
     * Details: 
     *     1. When referring to a pointcut expression, it must be a method name + (), such as "pointcut()".
     *     2. Used in the current section, you can write the method name directly. It must be a fully qualified method name used in other aspects.
     */
    @Pointcut("execution(* com.jason.service.impl.*.*(..))")
    public void pointcut() {}

    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        System.out.println("Method. The parameters are:"+ Arrays.toString(args));
    }

    @After("pointcut()")
    public void after() {
        System.out.println("Method. Do it anyway.");
    }

    @AfterReturning(value = "pointcut()",returning = "rtValue")
    public void afterReturning(Object rtValue) {
        System.out.println("Method is executed when it returns. The return value is:"+rtValue);
    }

    @AfterThrowing(value = "pointcut()",throwing = "e")
    public void afterThrowing(Throwable e) {
        System.out.println("Method is executed when an error is thrown. The exception is:"+e.getMessage());
    }

    /**
     * Around Advice 
     * @param pjp
     * @return 
     */
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        // Define return value
        Object rtValue = null;
        try{
            // Before advice 
            System.out.println("Before advice ");
            // 1. Get parameters
            Object[] args = pjp.getArgs();
            // 2. Implement the pointcut approach
            rtValue = pjp.proceed(args);
            // Post notification
            System.out.println("Post notification");
        }catch (Throwable t){
            // Exception notification
            System.out.println("Exception notification");
            t.printStackTrace();
            throw t;
        }finally {
            // Final notice
            System.out.println("Final notice,");
        }
        return  rtValue;
    }
}

4, Annotation mode

1. Annotation

When using annotations to drive aop development, we should make it clear that annotations replace the following line of configuration in the configuration file:

<!-- open spring Comment on aop Support of -->
<aop:aspectj-autoproxy />

Replace the above configuration with the following annotation in the configuration class:

@Configuration
@ComponentScan("com.jason") 
@EnableAspectJAutoProxy // Enable spring support for annotation AOP 
public class SpringConfiguration {
}

Article content output source: pull hook education Java high salary training camp;

Keywords: Java Spring AOP

Added by rationalrabbit on Tue, 25 Jan 2022 21:49:13 +0200