Java core framework 04 spring AOP

1. AOP introduction

1.1 basic concepts of AOP

AOP (Aspect Oriented Programming) is a technology of Aspect Oriented Programming, which realizes the unified maintenance of program functions through precompiled mode and dynamic agent during operation. AOP is the continuation of OOP, a hot spot in software development and an important content of Spring framework.

1.2 role of AOP

The core function of AOP is to enhance the function of the program without modifying the code during the program running. Make the essential public functions into aspects, and cut into the code to run as the program runs. When writing business, we only focus on the core functions, and no longer consider the public functions such as transaction and log, which reduces the coding burden and focuses more on business.

 

1.3 AOP terminology

1. Aspect

The concerns about which methods to intercept and how to deal with them after interception are called facets

2. Join point

The intercepted point. Because Spring only supports connection points of method types, connection points in Spring refer to the intercepted methods. In fact, connection points can also be fields or constructors

3. pointcut

Definition of interception of connection points

4. advice

The so-called notification refers to the code to be executed after intercepting the connection point. Notifications are divided into five categories: pre, post, exception, final and surround notifications

5. Target object

The process of applying facets to the target object and causing the proxy object to be created

6. Import \ weave (introduction, weave)

Without modifying the code, you can dynamically add some methods or fields to the class at run time

2. Implementation of AOP

2.1 AOP configuration steps

2.1.1 import dependency

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.5</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.5</version>
        </dependency>

2.1.2 preparation notice

/**
 * Log output notification class
 */
public class LogAdvise {

    public void beforeLog(){
        System.out.println("Method starts execution!");
    }

    public void afterLog(){
        System.out.println("Method post execution!");
    }

    public void afterReturning(){
        System.out.println("Method returned data");
    }

    public void afterThrowing(){
        System.out.println("Method threw an exception");
    }

    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("around Method name:" + joinPoint.getSignature().getName());
        System.out.println("around --Front");
        //Original method
        joinPoint.proceed();
        System.out.println("around --Post");
    }
}

2.1.3 AOP configuration

<?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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--Configure scanning of packages-->
    <context:component-scan base-package="com.blb.aop_demo"></context:component-scan>
    <!--Configure notification class-->
    <bean id="logAdvise" class="com.blb.aop_demo.util.LogAdvise"></bean>
    <!--Configure section-->
    <aop:config>
        <!--Configure pointcuts-->
        <aop:pointcut id="pc" expression="execution(* com.blb.aop_demo.service.*Service.*(..))"/>
        <!--Configure section ref Is a notification class bean-->
        <aop:aspect id="aspect1" ref="logAdvise">
            <!--Before advice  method Is the corresponding notification method pointcut-ref Is the entry point-->
            <aop:before method="beforeLog" pointcut-ref="pc"></aop:before>
            <!--Post-->
            <aop:after method="afterLog" pointcut-ref="pc"></aop:after>
            <!--Post return-->
            <aop:after-returning method="afterReturning" pointcut-ref="pc"></aop:after-returning>
            <!--Post throw anomaly-->
            <aop:after-throwing method="afterThrowing" pointcut-ref="pc"></aop:after-throwing>
            <!--surround-->
            <aop:around method="around" pointcut-ref="pc"></aop:around>
        </aop:aspect>
    </aop:config>
</beans>

2.1.4 testing

At com.blb.aop_ Add several Service classes under demo.Service package for testing

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");
GoodsService goodsService = context.getBean(GoodsService.class);
goodsService.queryGoods();
goodsService.queryGoodsById(1);
goodsService.createGoods();
goodsService.updateGoods();
goodsService.deleteGoodsById(1);

 

2.1.5 configuration details

aop:pointcut is the pointcut configuration

The core is expression, which controls the application scope of the section through the expression

Syntax:

Execution (return value of access modifier package name. Class name. Method name (parameter type, parameter type...))

Wildcard:

*Represents characters of any length
​
.. Instead of a sub package or any parameter

3. Annotation configuration of AOP

3.1 common AOP related notes

@The Aspect is configured on the Aspect class

@PointCut("expression") configures the pointcut and adds it to the method

@Before configuring the pre notification method

@After configure post notification method

@Around configure surround notification method

@AfterReturning configures the post return value notification method

@AfterThrowing configures the post throw exception notification method

3.2 AOP configuration

1) Configuration class

@ComponentScan(basePackages = "com.blb.aop_demo")
@Configuration
//Start annotation configuration for AspectJ
@EnableAspectJAutoProxy
public class AopConfig {
}

2) Log section

/**
 * Log section
 */
@Aspect
@Component
public class LogAspect {

    //Configure pointcuts
    @Pointcut("execution(* com.blb.aop_demo.service.*Service.*(..))")
    public void pointcut(){
    }

    //Configure notification method
    @Before("pointcut()")
    public void beforeLog(){
        System.out.println("This is the pre notification method!!");
    }
}

3) Testing

AnnotationConfigApplicationContext context2 = new   
                              AnnotationConfigApplicationContext(AopConfig.class);
GoodsService goodsService = context2.getBean(GoodsService.class);
goodsService.queryGoods();
goodsService.queryGoodsById(1);
goodsService.createGoods();
goodsService.updateGoods();
goodsService.deleteGoodsById(1);

4. Log tracking cases

4.1 case overview

After the actual project is deployed online, it is necessary to locate the bug s through log collection. If the log tracking code is written in all methods, it will be very cumbersome and the code is not conducive to maintenance. If AOP is used, this problem can be well solved.

4.2 case realization

1) Import log4j dependency

2) Add log4j.properties

3) Write log section

/**
 * Log4j Log output section
 */
@Aspect
@Component
public class Log4jAspect {

    //Create log object
    private Logger logger = Logger.getLogger(Log4jAspect.class);

    //Add log trace to all methods of all service classes
    @Pointcut("execution(* com.blb.aop_demo.service.*Service.*(..))")
    public void logPointcut(){
    }

    //Configure surround notifications
    @Around("logPointcut()")
    public Object aroundLog(ProceedingJoinPoint point) throws Throwable {
        //Record time before method execution
        long start = System.currentTimeMillis();
        //Print method name
        if(logger.isDebugEnabled()){
            logger.debug("Current execution method:" + point.getSignature().getName());
        }
        //Print parameters
        Object[] args = point.getArgs();
        for(Object arg : args){
            if(logger.isDebugEnabled()){
                logger.debug("Parameters:"+arg);
            }
        }
        //Print return value
        Object result = point.proceed();
        if(logger.isDebugEnabled()){
            logger.debug("Method return value:" +result);
        }
        //Print execution time
        long end = System.currentTimeMillis();
        if(logger.isDebugEnabled()){
            logger.debug("Method execution time:" +(end - start));
        }
        return result;
    }
}

Tags: Java Spring Back-end

Posted on Fri, 29 Oct 2021 03:21:29 -0400 by alan007