Spring AOP 2. X implementation of pre, post, surround and exception notification based on namespace configuration

Posted by snidog on Fri, 21 Feb 2020 07:17:00 +0100

SpringAop 2.x

Introduction:

The principle of namespace based configuration is to use post processor, which is simpler.

Characteristic:

Simplified configuration,

There is no need to implement any interface when writing non intrusive notifications.

Use the AspectJ expression to define the tangent point.

Basic usage:

Configure advice

To define an enhanced class, you do not need to implement any interface, but there are many ways to write it.

Configure PointCut and weave in

AspectJ expression

Introduction: tangent expression, an expression used to define the tangent position.

Usage:

Within syntax: within (package name. Class name) matches all methods in the class.

execution

A specific method that matches a specific parameter of a specific return value type in a specific class in a specific package.

Syntax: execution (expression)

Expression: return value type package name. Class name. Method name (parameter type)

Wildcards: * and

... Indicates that the parameter is arbitrary.

Configuration mode:

Basic usage: add jar package

<dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!--ioc01-core-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>
        <!--ioc01-bean-->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <!--ioc01-context-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <!--ioc01-expression-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
        </dependency>
        <!--Aop rely on-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
        <!--cglib technology-->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
        </dependency>

Writing interface UserService

package springaop07.service;


/**
 * package_name:springaop01.service
 *
 * author:Xu Yayuan Date:2020/2/18 18:29
 * Project Name: springDemo01
 * Description:
 **/
public interface UserService {

    /**
     * @Author : Xu Ya Yuan
     * @Date : 2020/2/18 20:34
     * @param username
     * @param password
     * @Description :
     */
    void login(String username, String password);
}

Implementation class UserServiceImpl of writing interface

package springaop07.service.impl;

import springaop07.service.UserService;

/**
 * package_name:springaop01.service.impl
 * Author:Xu Ya Yuan
 * Date:2020/2/18 18:29
 * Project Name: springDemo01
 * Desription:
 **/
public class UserServlceImpl implements UserService {


    /**
     * @param password
     * @param username
     * @Author : Xu Ya Yuan
     * @Date : 2020/2/18 21:03
     * @Description :
     */

    @Override
    public void login(String username, String password) {

        System.out.println("loginUserServiceImpl Login method execution:" + username + "    " + password);
        //Uncomment on exception notification
        //int i = 10/0;
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Written notice

package springaop07.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * package_name:springaop07.advice
 *
 * @author:Xu Yayuan Date:2020/2/20 14:06
 * Project Name: springDemo01
 * Description:TODO
 * Version: 1.0
 **/

public class UserAdvice {
    private Long time;

    public Long getTime() {
        return time;
    }

    public void setTime(Long time) {
        this.time = time;
    }

    //Configure pre notification method
    public void log(JoinPoint joinPoint){
        //autograph
       Signature signature = joinPoint.getSignature();
       //Method name
       String methodName = signature.getName();
       //Transform to method signature, which is essentially method signature
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        //parameter
       Object [] args = joinPoint.getArgs();
       //Target class
       Object target =  joinPoint.getThis();

        System.out.println("Before advice: "+"methodName: "+methodName+" "+"args:"+Arrays.toString(args) +" "+"target: "+target);
    }
    //Configure post notification method
    public void afterLog(JoinPoint joinPoint,Object value){

        //autograph
        Signature signature = joinPoint.getSignature();
        //Method name
        String methodName = signature.getName();
        //Transform to method signature, which is essentially method signature
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        //parameter
        Object [] args = joinPoint.getArgs();
        //Target class
        Object target =  joinPoint.getThis();

        System.out.println("Post notification: "+"methodName: "+methodName+" "+"args:"+Arrays.toString(args) +" "+"target: "+target);
    }

    public void throwLog(JoinPoint joinPoint,Exception ex){
        //autograph
        Signature signature = joinPoint.getSignature();
        //Method name
        String methodName = signature.getName();
        //Transform to method signature, which is essentially method signature
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        //parameter
        Object [] args = joinPoint.getArgs();
        //Target class
        Object target =  joinPoint.getThis();

        System.out.println("Abnormal notice: "+"methodName: "+methodName+" "+"args:"+Arrays.toString(args) +" "+"target: "+target);
    }
    public Object aroundLog(ProceedingJoinPoint joinPoint) throws Throwable {

        System.out.println("Before method execution");
        Long startTime = System.currentTimeMillis();
         Object proceed =   joinPoint.proceed();
        Long endTime = System.currentTimeMillis();
        if (endTime-startTime > time){
            System.out.println("Send short message to administrator:Too long login time, please optimize");
        }else {
            System.out.println("Cost after method execution["+(endTime-startTime)+"]"+"ms");
        }
        return proceed;
    }

}

Configure the spring.xml configuration file
When implementing a notification, cancel the annotation of the notification. In the following configuration file
Note that the exception notification is cancelled in the UserServiceImpl class / / int i = 10/0; this annotation

<?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">

    <!--springAop 2.x To configure-->
    <!--Configure target class instance-->
    <bean id="userService" class="springaop07.service.impl.UserServlceImpl"/>

    <!--To configure advice notice-->
    <bean id="userAdvice" class="springaop07.advice.UserAdvice">
        <property name="time" value="3000"/>
    </bean>
    <!--Configure entry point and weave in lead in <aop:config>Namespace-->
    <aop:config>
        <!--Configuration entry point-->
        <aop:pointcut id="us" expression="within(springaop07.service.impl.UserServlceImpl)"/>
        <!--Weaving configuration notice-->
        <aop:aspect ref="userAdvice">
        
            <!--Advance notice will userAdvice Class log Method woven into us Corresponding entry point-->
            <!--<aop:before method="log" pointcut-ref="us"/>-->
            <!--Post notification will userAdvice Class afterLog Method woven into us Corresponding entry point-->
            <!--<aop:after-returning method="afterLog" pointcut-ref="us" returning="value"/>-->
            <!--The notice of change will userAdvice Class afterLog Method woven into us Corresponding entry point-->
            <!--<aop:after-throwing method="throwLog" pointcut-ref="us" throwing="ex"/>-->
            <!--Surround notification will userAdvice Class afterLog Method woven into us Corresponding entry point-->
            <aop:around method="aroundLog" pointcut-ref="us"/>
        </aop:aspect>
    </aop:config>
</beans>

The results of the circular notification are as follows:

The results of the pre notification are shown in the figure below:

The post notification results are shown in the figure below:

The result of exception notification is shown in the figure below:

Published 64 original articles, won praise 1, visited 838
Private letter follow

Topics: Spring Junit Java xml