Spring series. AOP use

AOP introduction

Using the object-oriented method can organize the code well, and also can realize code reuse in the way of inheritance. However, there will always be some duplicate code in the project, and it is not convenient to use inheritance methods to reuse and manage them, such as general log printing, transaction processing and security check. We can encapsulate these codes and make them into general modules, but we still need to call the display at every place in the code, which is inconvenient to use. This is the time to take advantage of AOP.

AOP is a programming paradigm, which is used to solve specific problems and cannot solve all problems. It can be regarded as a supplement to OOP. Common programming paradigms include:

  • Process oriented programming;
  • Object oriented programming;
  • Function oriented programming (functional programming);
  • Event driven programming (common in GUI Development);
  • Face to face programming

Common usage scenarios of AOP

  • Performance monitoring, recording the call time before and after the method call, and alarming when the method execution is too long or timeout;
  • Cache agent, which caches the return value of a method. The next time the method is executed, it is directly obtained from the cache;
  • Software cracking, using AOP to modify the judgment logic of software verification class;
  • Record log, record system log before and after method execution;
  • Workflow system, workflow system needs to mix business code and process engine code to execute together, then we can use AOP to separate them and dynamically hook up business;
  • Permission verification: verify whether the current method has permission to execute before method execution. If not, throw an exception for execution without permission, which is caught by business code;
  • Transactions.

Spring AOP related concepts

  • AOP: the idea of dynamically cutting some common code into the specified method and location of a class at run time (or compile time or load time) is face-to-face programming;
  • Aspect: a modulation of a concern that cuts across multiple classes. In Spring, facet is a class marked with @ AspectJ. Don't think too complicated;
  • Join point: a point in the execution of a method. It is a point that can insert a tangent during the execution of an application. This point can be when a method is called, when an exception is thrown, or even when a field is modified. The tangent code can use these points to insert into the normal process of application and add new behaviors;
  • advice: describe what work is to be done in the section and at what time;
  • Pointcut: used to match a set of connection points, and pointcut will be associated with advice. When the connection points matched by pointcut are executed, advice code will be executed;
  • Introduction
  • Target object: the object woven into the section;
  • AOP proxy: an object wrapped with faceted code and target code. JDK dynamic proxy and
    CGLIB. By default, JDK dynamic proxy is used. However, if the class being proxied does not implement an interface or the user forces CGLIB, Spring will use CGLIB proxy;
  • Weaving: the process of adding faceted code to the target code. Weaving types include compile time weaving, load time weaving and run time weaving (Spring is run-time weaving)

Spring AOP can apply five types of notifications:

  • Pre notification (Before): calling the notification function before the target method is invoked.
  • Post notification (After): call notification after completion of the target method, and will not care what the output of the method is. (execute regardless of whether the execution is successful or not)
  • Return notification (After-returning): call notification after successful execution of the target method.
  • Exception notification (After-throwing): calling a notification after the target method throws an exception.
  • Around: a notification wraps the notified method and performs custom behavior before and after the notified method call.

Spring AOP related

Aop on

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AopConfig {
}

If you use the traditional configuration mode, you can open the AOP function as follows.

<aop:aspectj-autoproxy/>

Define an Aspect

Aspects (classes annotated with @Aspect) can have methods and fields, the same as any other class. They can also contain pointcut, advice, and introduction (inter-type) declarations.

You can define it in the way of ordinary beans or with @ Aspect annotation. Once a class is labeled as a facet class, it does not become a proxy for other facets.

Define a PointCut

Facet expressions can be composed of indicators, wildcards, and operators.

  1. Designators
  • Match method execution() (focus on mastering...)
  • Match annotation @ target() @args() @within() @annotation()
  • Match package / type within()
  • Match object this() bean() target()
  • Match parameter args()
  1. Wildcards (wildcards)
  • *Match any number of characters
  • +Match the specified class and its subclasses
  • ... is generally used to match any parameter's subpackage or parameter
  1. Operators (operators)
  • &&And operators
  • ||Or operator
  • ! non operator

Here is an example of defining PointCut

package com.csx.demo.spring.boot.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class MyAspect {

    //PointCut matching method must be the method of bean in Spring
    //Pointcut can be defined in the following ways or combined by & &|, and
    //The entry points defined below can be combined through & &|

    private static Logger logger = LoggerFactory.getLogger(MyAspect.class);

    //*: the return value representing the method can be of any type
    //The whole expression matches any echo method under the controller package. The method input parameter is arbitrary
    @Pointcut("execution(* com.csx.demo.spring.boot.controller.*.echo(..))")
    public void pointCut1(){}

    //The echo method must have a parameter of any type
    @Pointcut("execution(* com.csx.demo.spring.boot.controller.*.echo(*))")
    public  void pointCut2(){}

    //The echo method must have two parameters. The first type is arbitrary and the second type must be String
    @Pointcut("execution(* com.csx.demo.spring.boot.controller.*.echo(*,String))")
    public void pointCut3(){}

    //Any method of any class under the contour package and its sub package
    //Note that with and @ with are both at the package level
    @Pointcut("within(com.csx.demo.spring.boot.controller..*)")
    public void pointCut4(){}

    //Use the RestController annotation to annotate any method of any class
    @Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
    public void pointCut5(){}

    //Similar to @ Within
    @Pointcut("@target(org.springframework.web.bind.annotation.RestController)")
    public void pointCut10(){}

    //MyService is the interface to implement any method of the class
    //If MyService is a class, match all the methods inside the class
    @Pointcut("this(com.csx.demo.spring.boot.service.MyService)")
    public void pointCut6(){}

    @Pointcut("this(com.csx.demo.spring.boot.service.MyServiceImpl)")
    public void pointCut7(){}

    //All methods inside a bean
    @Pointcut("bean(myServiceImpl)")
    public void pointCut8(){}

    //@Annotation for class by within and @ target ,@annotation Is a comment on the method
    //Match any annotation getmapping annotation
    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
    public void pointCut9(){}

    //Only one parameter is matched, and the parameter type is String
    @Pointcut("args(String)")
    public void pointCut11(){}


    @Before("pointCut1()")
    public void befor(){
        logger.info("Before advice  vvvv...");
        logger.info("I need to do something...");
    }

    @After("pointCut1()")
    public void after(){
        logger.info("Post notice");
    }

    @AfterReturning("pointCut1()")
    public void afterReturn(){
       logger.info("Post return");
    }

    @Around("pointCut1()")
    public void around(ProceedingJoinPoint point) throws Throwable {
        logger.info("Around Advice ...");
        logger.info("I need to do something...");
        point.proceed();
        logger.info("End wrap notification");
    }

}

Keywords: Java Spring Programming JDK

Added by dessolator on Tue, 16 Jun 2020 05:58:28 +0300