10. Understanding of SpringAop of SpringBoot

Understanding of spring AOP

01. Learning objectives

  • Meet spring AOP
  • Understand the principle of the underlying implementation of spring AOP
    • JDK dynamic agent
    • CGLIB agent
  • Types of enhanced notifications for spring AOP
  • Definition of pointcut for spring AOP
  • What is the default Aop proxy mechanism in Spring?
  • What is the default Aop proxy mechanism in SpringBoot?
  • Actual development of spring AOP, log management, flow limiting processing, permission interception.
  • Spring MVC source code analyzes how post notifications are generated and managed with Aop.
  • Then learn the relationship between spring AOP and dynamic proxy in regression.
  • Why is spring AOP built on ioc?

02. Preparation

  • Create a springboot-aop-07 project
  • In project POM The aop dependency in XML is as follows:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

03. Get to know SpringAop

java learning curve, object-oriented, create class, create attribute, create method, create object, execute method, assign value to attribute, such as:

User pojo

package com.kuangstudy.first;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

/**
 * @author Feige
 * @Title: Learning companion product
 * @Description: Feige station B address: https://space.bilibili.com/490711252
 * Remember to pay attention to the third company!
 * @Description: We have a learning website: https://www.kuangstudy.com
 * @date 2021/12/21 22:05
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {
    private Integer userId;
    private String nickname;
    private String password;
}

Order pojo

package com.kuangstudy.first;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

/**
 * @author Feige
 * @Title: Learning companion product
 * @Description: Feige station B address: https://space.bilibili.com/490711252
 * Remember to pay attention to the third company!
 * @Description: We have a learning website: https://www.kuangstudy.com
 * @date 2021/12/21 22:05
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Order {
    private Integer userId;
    private Integer orderId;
    private String price;
    private String orderTradeNo;
}

User service

package com.kuangstudy.first;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * @author Feige
 * @Title: Learning companion product
 * @Description: Feige station B address: https://space.bilibili.com/490711252
 * Remember to pay attention to the third company!
 * @Description: We have a learning website: https://www.kuangstudy.com
 * @date 2021/12/21 22:05
 */
@Slf4j
@Service
public class UserService {

    /**
     * User registration
     *
     * @param user
     */
    public void saveUser(User user) {
        log.info("User registration....");
    }

    /**
     * Modify user
     *
     * @param user
     */
    public void updateUser(User user) {
        log.info("Modify user....");
    }


    /**
     * delete user
     *
     * @param userId
     */
    public void delUser(Integer userId) {
        log.info("delete user....{}", userId);
    }

}

Order service

package com.kuangstudy.first;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * @author Feige
 * @Title: Learning companion product
 * @Description: Feige station B address: https://space.bilibili.com/490711252
 * Remember to pay attention to the third company!
 * @Description: We have a learning website: https://www.kuangstudy.com
 * @date 2021/12/21 22:05
 */
@Slf4j
@Service
public class OrderService {

    /**
     * Order registration
     *
     * @param order
     */
    public void saveOrder(Order order) {
        log.info("Order registration....");
    }

    /**
     * Modify order
     *
     * @param order
     */
    public void updateOrder(Order order) {
        log.info("Modify order....");
    }


    /**
     * Delete order
     *
     * @param orderId
     */
    public void delOrder(Integer orderId) {
        log.info("Delete order....{}", orderId);
    }

}

Test code

package com.kuangstudy;

import com.kuangstudy.first.User;
import com.kuangstudy.first.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootAopApplicationTests {

    @Autowired
    private UserService userService;


    @Test
    void contextLoads() {
        // 1: User registration
        userService.saveUser(new User());
        // 2: User modification
        userService.updateUser(new User());
        // 3: User deletion
        userService.delUser(1);
    }

}

Print the test results as follows:

[KSD - CONSOLE] 2021-12-21 22:15:13:275 [main] [INFO ] com.kuangstudy.first.UserService saveUser 28 - User registration....
[KSD - CONSOLE] 2021-12-21 22:15:13:275 [main] [INFO ] com.kuangstudy.first.UserService updateUser 37 - Modify user....
[KSD - CONSOLE] 2021-12-21 22:15:13:275 [main] [INFO ] com.kuangstudy.first.UserService delUser 47 - delete user....1

The above code: in fact, it is a standard java object-oriented process to create objects and execute methods. In the development process, what should we do when we need to execute methods for objects, when we need to enhance the execution logic of methods, when we need to control permissions, and when we need to limit flow?

Important information

Object execution method =, aop, which is actually a mechanism to enhance the processing of crosscutting logic in the process of object execution method-- OOP

We write code to catch up with the realm

  • High cohesion and low coupling

    • Interface
    • oop
    • Message queue
    • Design pattern
    • SPI
  • Try to use object-oriented thinking

    • enumeration

04. Log development requirement scenario

We now want to perform order enhancement log processing for all user interfaces and order interfaces in the program?

A Log class will be defined:

Role of log scenario requirements

  • It can help us eliminate the time-consuming problem of the implementation method
  • In this way, we can optimize and deal with the time-consuming problems of execution methods

pojo of log

package com.kuangstudy.first;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

/**
 * @author Feige
 * @Title: Learning companion product
 * @Description: Feige station B address: https://space.bilibili.com/490711252
 * Remember to pay attention to the third company!
 * @Description: We have a learning website: https://www.kuangstudy.com
 * @date 2021/12/21 22:05
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Logs {
    private Integer id;
    private String classname;
    private String method;
    private String time;
    private String params;
}

Log processing service

package com.kuangstudy.first;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * @author Feige
 * @Title: Learning companion product
 * @Description: Feige station B address: https://space.bilibili.com/490711252
 * Remember to pay attention to the third company!
 * @Description: We have a learning website: https://www.kuangstudy.com
 * @date 2021/12/21 22:05
 */
@Slf4j
@Service
public class LogService {

    public void saveLog(Logs logs) {
        log.info("The log you saved is:{}", logs);
    }
}

Record function of development log saving

Our normal thinking and development process are as follows:

The user service needs to record logs as follows:

package com.kuangstudy.first;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author Feige
 * @Title: Learning companion product
 * @Description: Feige station B address: https://space.bilibili.com/490711252
 * Remember to pay attention to the third company!
 * @Description: We have a learning website: https://www.kuangstudy.com
 * @date 2021/12/21 22:05
 */
@Slf4j
@Service
public class UserService {


    @Autowired
    private LogService logService;

    /**
     * User registration
     *
     * @param user
     */
    public void saveUser(User user) {
        log.info("User registration....");

        // Log
        Logs logs = new Logs();
        logs.setClassname("com.kuangstudy.service.UserService");
        logs.setMethod("saveUser");
        logs.setId(1);
        logs.setParams(user.toString());
        logs.setTime("100ms");
        logService.saveLog(logs);
    }

    /**
     * Modify user
     *
     * @param user
     */
    public void updateUser(User user) {
        log.info("Modify user....");

        // Log
        Logs logs = new Logs();
        logs.setClassname("com.kuangstudy.service.UserService");
        logs.setMethod("updateUser");
        logs.setId(1);
        logs.setParams(user.toString());
        logs.setTime("100ms");
        logService.saveLog(logs);
    }


    /**
     * delete user
     *
     * @param userId
     */
    public void delUser(Integer userId) {
        log.info("delete user....{}", userId);

        // Log
        Logs logs = new Logs();
        logs.setClassname("com.kuangstudy.service.UserService");
        logs.setMethod("delUser");
        logs.setId(1);
        logs.setParams(userId + "");
        logs.setTime("100ms");
        logService.saveLog(logs);
    }

}

Order service record log

package com.kuangstudy.first;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author Feige
 * @Title: Learning companion product
 * @Description: Feige station B address: https://space.bilibili.com/490711252
 * Remember to pay attention to the third company!
 * @Description: We have a learning website: https://www.kuangstudy.com
 * @date 2021/12/21 22:05
 */
@Slf4j
@Service
public class OrderService {

    @Autowired
    private LogService logService;

    /**
     * Order registration
     *
     * @param order
     */
    public void saveOrder(Order order) {
        log.info("Order registration....");

        // Log
        Logs logs = new Logs();
        logs.setClassname("com.kuangstudy.service.OrderService");
        logs.setMethod("saveOrder");
        logs.setId(1);
        logs.setParams(order.toString());
        logs.setTime("100ms");
        logService.saveLog(logs);
    }

    /**
     * Modify order
     *
     * @param order
     */
    public void updateOrder(Order order) {
        log.info("Modify order....");

        // Log
        Logs logs = new Logs();
        logs.setClassname("com.kuangstudy.service.OrderService");
        logs.setMethod("updateOrder");
        logs.setId(1);
        logs.setParams(order.toString());
        logs.setTime("100ms");
        logService.saveLog(logs);
    }


    /**
     * Delete order
     *
     * @param orderId
     */
    public void delOrder(Integer orderId) {
        log.info("Delete order....{}", orderId);

        // Log
        Logs logs = new Logs();
        logs.setClassname("com.kuangstudy.service.OrderService");
        logs.setMethod("delOrder");
        logs.setId(1);
        logs.setParams(orderId.toString());
        logs.setTime("100ms");
        logService.saveLog(logs);
    }

}

Perform test

package com.kuangstudy;

import com.kuangstudy.first.Order;
import com.kuangstudy.first.OrderService;
import com.kuangstudy.first.User;
import com.kuangstudy.first.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class SpringbootAopApplicationTests {

    @Autowired
    private UserService userService;
    @Autowired
    private OrderService orderService;


    @Test
    void contextLoads() {
        // 1: User registration
        userService.saveUser(new User());
        // 2: User modification
        userService.updateUser(new User());
        // 3: User deletion
        userService.delUser(1);
    }

    @Test
    public void testOrder() {
        // 1: User registration
        orderService.saveOrder(new Order());
        // 2: User modification
        orderService.updateOrder(new Order());
        // 3: User deletion
        orderService.delOrder(1);
    }

}

results of enforcement

[KSD - CONSOLE] 2021-12-21 22:33:38:208 [main] [INFO ] com.kuangstudy.first.UserService saveUser 33 - User registration....
[KSD - CONSOLE] 2021-12-21 22:33:38:208 [main] [INFO ] com.kuangstudy.first.LogService saveLog 19 - The log you saved is: Logs(id=1, classname=com.kuangstudy.service.UserService, method=saveUser, time=100ms, params=User(userId=null, nickname=null, password=null))
[KSD - CONSOLE] 2021-12-21 22:33:38:210 [main] [INFO ] com.kuangstudy.first.UserService updateUser 51 - Modify user....
[KSD - CONSOLE] 2021-12-21 22:33:38:211 [main] [INFO ] com.kuangstudy.first.LogService saveLog 19 - The log you saved is: Logs(id=1, classname=com.kuangstudy.service.UserService, method=updateUser, time=100ms, params=User(userId=null, nickname=null, password=null))
[KSD - CONSOLE] 2021-12-21 22:33:38:211 [main] [INFO ] com.kuangstudy.first.UserService delUser 70 - delete user....1
[KSD - CONSOLE] 2021-12-21 22:33:38:211 [main] [INFO ] com.kuangstudy.first.LogService saveLog 19 - The log you saved is: Logs(id=1, classname=com.kuangstudy.service.UserService, method=delUser, time=100ms, params=1)


Results of order execution

[KSD - CONSOLE] 2021-12-21 22:34:38:089 [main] [INFO ] com.kuangstudy.first.OrderService saveOrder 28 - Order registration....
[KSD - CONSOLE] 2021-12-21 22:34:38:090 [main] [INFO ] com.kuangstudy.first.LogService saveLog 19 - The log you saved is: Logs(id=1, classname=com.kuangstudy.service.OrderService, method=saveOrder, time=100ms, params=Order(userId=null, orderId=null, price=null, orderTradeNo=null))
[KSD - CONSOLE] 2021-12-21 22:34:38:096 [main] [INFO ] com.kuangstudy.first.OrderService updateOrder 46 - Modify order....
[KSD - CONSOLE] 2021-12-21 22:34:38:096 [main] [INFO ] com.kuangstudy.first.LogService saveLog 19 - The log you saved is: Logs(id=1, classname=com.kuangstudy.service.OrderService, method=updateOrder, time=100ms, params=Order(userId=null, orderId=null, price=null, orderTradeNo=null))
[KSD - CONSOLE] 2021-12-21 22:34:38:097 [main] [INFO ] com.kuangstudy.first.OrderService delOrder 65 - Delete order....1
[KSD - CONSOLE] 2021-12-21 22:34:38:097 [main] [INFO ] com.kuangstudy.first.LogService saveLog 19 - The log you saved is: Logs(id=1, classname=com.kuangstudy.service.OrderService, method=delOrder, time=100ms, params=1)


What do you have to learn from the above code?

1. Through the above typical case, we found that the object execution method needs to do some extra things, and you have to do these things.

2. The code of log logic is tightly coupled, which pollutes some business logic. And it is not convenient for subsequent maintenance.

3. Now the whole log above will be intercepted. Is it flexible? If I want to consider that some methods need to be intercepted, but they don't, what should I do? For example, subsequent flow restriction and permission interception

05. Solutions to the above problems

  • AOP

06. Can we optimize the above code through some schemes?

01. Packaging method

01. Overload of log method

package com.kuangstudy.first;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * @author Feige
 * @Title: Learning companion product
 * @Description: Feige station B address: https://space.bilibili.com/490711252
 * Remember to pay attention to the third company!
 * @Description: We have a learning website: https://www.kuangstudy.com
 * @date 2021/12/21 22:05
 */
@Slf4j
@Service
public class LogService {

    public void saveLog(Logs logs) {
        log.info("The log you saved is:{}", logs);
    }

    public void saveLog(String classname,String method,String time,String params) {
        Logs logs = new Logs();
        logs.setClassname("com.kuangstudy.service.OrderService");
        logs.setMethod("updateOrder");
        logs.setId(1);
        logs.setParams(params);
        logs.setTime("100ms");
        log.info("The log you saved is:{}", logs);
    }
}

Modify the user registration method

    /**
     * User registration
     *
     * @param user
     */
    public void saveUser(User user) {
        log.info("User registration....");
        // Log
        logService.saveLog("com.kuangstudy.service.UserService","saveUser","100ms",user.toString());
    }

Others, and so on

02: Problem

It doesn't solve the fundamental problem. This must be abandoned.

Interceptor (interceptor of spring MVC)

Core idea: jdk dynamic agent must implement the interface: HandlerInterceptor

The reason why the interceptor must implement an interface: HandlerInterceptor is that the jdk dynamic proxy must have an interface to create a proxy object

Define interceptor

LogInterceptor implements HandlerInterceptor to cover three methods. Then, the logs to be processed are processed in the handler.

  • Register interceptor
  • Configure interception and de routing

There is a problem with the interceptor

  • Service related to container (servlet) (request, response, freemaker)

  • The granularity is too coarse. Because the interceptor is determined according to the route (request mapping), you can only intercept the controller layer, not the service layer. The dao layer, that is, nothing other than the controller, is handled.

    @PostMaiing("/save/userorder")
    public void saveUserOrder(){// --- 3s ~5s
       // Save order
       orderServicee.saveOrder(); // It is necessary to record the log and limit the current for 100ms
       // User points increased
       userService.updateUserjifen();//This does not require 800ms
    }
    
  • Logic processing is inconvenient. It's too heavy.

    • What if there is an exception (what about this problem?)
    • During method execution,
    • After method execution
    • After execution result
  • If there are multiple processes, you must define multiple interceptors. In fact, the granularity is too large. Configuration and maintenance are catastrophic.

addRegisterInterceptor(new LogInterceptor())
.addPatterns("/user/**","/order/**");

addRegisterInterceptor(new PersmissionInterceptor())
.addPatterns("/user/save","/user/update","/order/makeorder");

jdk dynamic proxy, cglib code

Use the underlying mechanism of aop, such as jdk dynamic proxy or cglib proxy. Yes, no problem. However, it faces the following problems:

Problems faced:

  • Fine control must be written by yourself,
    • For example: conditional judgment, which methods to enter and which methods not to enter. You must control yourself
    • If there are multiple proxy objects, the proxy class creation must also be defined by itself (facet, connection point, tangent point, weaving, notification enhancement, all must be encapsulated by itself)
    • How to ensure the execution order of multi-agent classes. You also need to control yourself
  • You must be very familiar with the underlying mechanism and life cycle of spring IOC. Because you must use dynamic proxy, whether you implement it with jdk dynamic proxy or cglib proxy, their goal is to convert the target object into: proxy object.
  • Because only when the proxy object executes the method, it will go to the proxy class (aspect) for logic enhancement. (we deal with)

07. Importance of AOP

  • The bottom layer of aop is the combination of jdk dynamic agent and cglib agent.
  • It can solve all the above problems.
  • aop automatically converts all enhanced objects in spring IOC into proxy objects.

08. Underlying implementation mechanism of Aop

  • Dynamic implementation of jdk
  • cglib proxy implementation

Either way: its goal is to transform spring IOC objects into proxy objects.

This is a normal springioc object

09. Convert Springioc objects into proxy objects?

Why is it used for log processing? What are your log interception processing and core points?

  • View the execution duration of the current class
  • The time-consuming method can be judged according to the duration, and targeted troubleshooting and optimization can be carried out according to the time-consuming method.

01. Define log annotation

package com.kuangstudy.aop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author Feige
 * @Title: Learning companion product
 * @Description: We have a learning website: https://www.kuangstudy.com
 * @date 2021/12/21 23:21
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface KsdLog {

    String value() default "";
}

Why define an annotation:

  • It is equivalent to a small red flag. If the method needs to be intercepted by AOP, it will be annotated, and the red flag will appear on the method.
  • Because spring AOP's pointcut expression is annotated, the annotated method can be controlled to be notified (the location of enhanced logic)
  • Can I do without notes? Sure, but it's not flexible. Look at the scene
    • execution expression (transaction control)
    • within
    • target (targeted)
    • args (processing for)
    • this
    • Annotation – fine grained

02. Define section

  • @Component
    • Let the spring IOC container manage this aspect and become a family.
  • @Aspect
    • Mark as cut
  • Connection point
    • Tangent expression
  • notice
    • Pre Advice - @ before (tangent point or tangent point expression)
    • Post Advice - @ after (tangent point or tangent point expression)
    • Exception Adivce – @ afterthrowing (pointcut or pointcut expression)
    • Surround advice - @ around (tangent point or tangent point expression)
    • Post return advice ----- @ afterreturning (tangent or tangent expression)
package com.kuangstudy.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

/**
 * @author Feige
 * @Title: Learning companion product
 * @Description: Feige station B address: https://space.bilibili.com/490711252
 * Remember to pay attention to the third company!
 * @Description: We have a learning website: https://www.kuangstudy.com
 * @date 2021/12/21 23:31
 */
@Component
@Aspect
@Slf4j
public class LogAspect {

    // 1: Define the Pointcut. All functions marked with @ KsdLog can enter the specific enhanced notification only through @ Pointcut judgment
    @Pointcut("@annotation(com.kuangstudy.aop.KsdLog)")
    public void logpointcut() {
    }


    @Around("logpointcut()")
    public void beforeAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        try {
            // 1: Start time of method execution
            long starttime = System.currentTimeMillis();
            // 2: Execute real method
            MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
            System.out.println(signature.getMethod().getName());
            System.out.println(signature.getReturnType());
            System.out.println(signature.getParameterNames());
            System.out.println(signature.getParameterTypes());
            //Let the annotated method execute!!!!
            Object methodReturnValue = proceedingJoinPoint.proceed();
            log.info("The return value of the currently executed method is:{}", methodReturnValue);
            // 3: End time of method execution
            long endtime = System.currentTimeMillis();
            // 4: Total time of method
            long total = endtime - starttime;
            log.info("Current method:{},The execution time is:{} ms", signature.getMethod().getName(), total);

        } catch (Throwable ex) {
            log.info("Error executing method.....,{}", ex);
            throw ex;
        }
    }

}

Add @ KsdLog annotation on the method to be intercepted

package com.kuangstudy.first;

import com.kuangstudy.aop.KsdLog;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author Feige
 * @Title: Learning companion product
 * @Description: Feige station B address: https://space.bilibili.com/490711252
 * Remember to pay attention to the third company!
 * @Description: We have a learning website: https://www.kuangstudy.com
 * @date 2021/12/21 22:05
 */
@Slf4j
@Service
public class OrderService {

    @Autowired
    private LogService logService;

    /**
     * Order registration
     *
     * @param order
     */
    @KsdLog
    public void saveOrder(Order order) {
        log.info("Order registration....");

        // Log
        Logs logs = new Logs();
        logs.setClassname("com.kuangstudy.service.OrderService");
        logs.setMethod("saveOrder");
        logs.setId(1);
        logs.setParams(order.toString());
        logs.setTime("100ms");
        logService.saveLog(logs);
    }

    /**
     * Modify order
     *
     * @param order
     */
    @KsdLog
    public void updateOrder(Order order) {
        log.info("Modify order....");

        // Log
        Logs logs = new Logs();
        logs.setClassname("com.kuangstudy.service.OrderService");
        logs.setMethod("updateOrder");
        logs.setId(1);
        logs.setParams(order.toString());
        logs.setTime("100ms");
        logService.saveLog(logs);
    }


    /**
     * Delete order
     *
     * @param orderId
     */
    @KsdLog
    public void delOrder(Integer orderId) {
        log.info("Delete order....{}", orderId);

        // Log
        Logs logs = new Logs();
        logs.setClassname("com.kuangstudy.service.OrderService");
        logs.setMethod("delOrder");
        logs.setId(1);
        logs.setParams(orderId.toString());
        logs.setTime("100ms");
        logService.saveLog(logs);
    }

}

The running test code is as follows:

At this time, we can clearly see that orderService has become a proxy object

10. Conclusion

  • In the spring underlying framework, it is the core foundation of ioc, which manages all bean objects of the project. If any method in these managed beans is managed in the aspect of aop. All these beans will be converted into proxy objects.
  • Because only when the proxy object executes the method can it enter the proxy class (aspect) for logic enhancement
  • If the method of adding conditions is not used, all of them will be abandoned and executed normally, and those that meet the conditions will enter the corresponding notice for logical enhancement.
  • By default, the code type of spring boot is cglib proxy, while the default proxy of spring framework is jdk dynamic proxy.
    • Because the jdk dynamic proxy must have an interface.
    • However, in some cases, the development does not need an interface and still needs to be able to support agents. Now, if you use jdk dynamic agents, you can't go to Xi'an
    • In order to solve this difficult situation, some people like class oriented programming, others like interface oriented programming, and spring is compatible and supported.

Keywords: Java Spring Boot Back-end

Added by websiteguy on Sun, 16 Jan 2022 16:29:41 +0200