5

1. AOP concept and when will it be used

  1. AOP is the aspect programming often referred to in Java, which is a kind of thinking or programming.
  2. AOP:Aspect-Oriented Programming
  3. AOP is a unique programming idea in the spring or springboot framework. Sometimes our business has some requirements such as verification before the beginning or other sending notification records after the end, although it can also be used in our own business. Writing, however, is verbose and messy code, because it is not our main business logic. At this time, you can use the AOP idea to make these non-primary logic such as verification or logging into an aspect, and use this aspect directly wherever you want to use it.
  4. To some extent, I think that the aspect is like a function. The function abstracts a piece of logic, and the aspect actually abstracts a piece of logic, but it is more decoupled than the function in terms of the overall project architecture.

Second, the position of AOP in the spring/springboot framework

  1. In the spring or springboot framework, there are two core ideas, one is IOC inversion of control, and the other is our AOP aspect programming.
  2. IOC: In projects, we often cooperate with multiple objects to implement our logic. The idea of IOC is to delegate the creation, management, and destruction of objects to the spring container to operate, rather than creating or managing these objects internally. Yu found an intermediary or agent to manage the object. ----- Literally means to reverse the responsibility of object control management to the spring container or agent. 【Object Decoupling】
  3. AOP: Abstract the non-main, non-functional code into an aspect, and decouple and reuse the code from the architecture. [Code decoupling]
  4. In development, we mainly create and manipulate different objects. When there are more objects, we try to decouple the objects. IOC comes in handy. Then, when we write specific business logic, non-functional or non-primary logic becomes more and more. The more time, try to abstract this piece of code, which can be abstracted into a function or aop aspect, and consider according to our own business to prevent too many if else judgments in the main business logic.

Three, AOP core knowledge points

备注:思考实现一个切面都需要哪些步骤?
(1)肯定需要写具体的切面业务逻辑(对应aspect)
(2)那写好逻辑后什么时候执行?是主要逻辑前还是主要逻辑后?(对应advice,执行时机)
(3)需要定义一个在哪里使用切面,比如某个insert方法要使用切面,校验insert之前的一些null或者空字符串(对应join point)
(4)不是所有方法都用到这个切面,怎么控制?(通过point cut来控制和匹配)
  • Junction

    join point, an execution point of the program, a method of similar class, a code block in the method

  • Entry point

    Point cut, capture the code structure of the connection point, define a code logic to capture the realization logic of a connection point

  • section

    Aspect, the specific code logic to be executed, is the logic implementation code that we want to verify, log, send SMS notifications, etc.

  • Notice

    advice, which defines when to execute the aspect at the connection point, including before (execute before the main logic), after (execute after the main logic), around (execute both before and after)

Fourth, simply implement an AOP (it is said that there are four common implementation methods, here only look at the springboot annotation method)

If you want to submit a leave application, the application form has gender, leave time, etc., before creating the application form, verify that the submitted parameters (sex, startDate, endDate) cannot be empty, and use the aspect to implement the verification logic.
  1. Customize an annotation ApplyAnnotation

    import java.lang.annotation.*;
    
    @Target({ ElementType.METHOD, ElementType.TYPE })
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface ApplyAnnotation {
    }
  1. Create the aspect class

    package portal.aop;
    
    import com.alibaba.fastjson.JSONObject;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang.StringUtils;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import java.util.Objects;
    
    /**
     * 申请单插入前校验的切面
     *
     */
    @Slf4j
    @Aspect
    @Component
    public class ApplyAspect {
    
        /**
         * 校验:对sex、startDate、endEnd参数进行校验
         * @param joinPoint
         * @throws RRException
         */
        @Before("@annotation(ApplyAnnotation)")
        public void before(JoinPoint joinPoint)  throws RRException {
            if(joinPoint.getArgs()!=null && joinPoint.getArgs().length>0) { //获取参数使用joinPoint.getArgs
                String json = JSONObject.toJSONString(joinPoint.getArgs()[0]);
              
                            // 将参数转换成一个entity对象
                UpdateApplyForm form = objectMapper.convertValue(joinPoint.getArgs()[0], UpdateApplyForm.class);
    
                if (Objects.isNull(form.getSex())) {
                    throw new Exception("参数错误,请检查参数sex是否传递");
                }
              
                            if (Objects.isNull(form.getStartDate())) {
                    throw new Exception("参数错误,请检查参数startDate是否传递");
                }
              
                  if (Objects.isNull(form.getEndDate())) {
                    throw new Exception("参数错误,请检查参数endDate是否传递");
                }
              
            }
        }
    
        @After("@annotation(ApplyViewAnnotation)")
        public void after(JoinPoint joinPoint) {
                    // 可以在主要逻辑之后执行一些 记录日志或者发送短信通知等逻辑
        }
    
       
    }
    
  1. Add notes where you want to use

            /**
             * 在controller的createApply方法使用注解
         * 创建一条请假申请,加上ApplyAnnotation注解后,会在执行createApply方法之前去调用切面的before方法进行校验
         * @param form
         * @return
         * @throws Exception
         */
        @PostMapping("/create-apply")
        @ApplyAnnotation
        public R createApply(@RequestBody UpdateApplyForm form) throws Exception {
              // 主要业务逻辑
            portalLogic.createApply(form);
            return R.ok();
        }
After experiencing the above examples, you will find that our main logic portalLogic.createApply(form) does not mix in some weird if else for verification, but directly implements these verification logic with an annotation, from the code From a hierarchical point of view, the code is more concise, and from an architectural point of view, the verification logic is decoupled from the main logic.

Five, the realization principle of AOP

  1. How is our AOP realized? How to make our main logic code execute the aspect logic before or after it is executed?
  2. In fact, AOP makes full use of the proxy to "weave" the logic of the aspect into our own main business code, which is not visible on the surface, but is implemented by the springboot framework through the proxy. (Actually, the proxy is divided into static proxy and dynamic proxy)
  3. An agent, what I understand is an intermediary, which entrusts an intermediary/agent to do what it wants to do, and all operations are carried out by the intermediary.
  4. There are two ways to implement the proxy used in AOP, jdk dynamic proxy and cglib proxy. It is necessary to understand the similarities and differences of these two proxy modes in advance.
  5. Details can be viewed: core source code principle detailed

繁星落眼眶
626 声望54 粉丝