Spring custom annotation and usage

First, JDK annotations are divided into two types:

1. Meta annotation (@ Target, @ Retention, @ Inherited, @ Documented)

2. Common annotations (@ Overried, @ Deprecated, @ suppresswarnings)

What is meta annotation?

It can be understood as the smallest annotation and basic annotation

What is the function of meta annotation?

Is to solve some duplicate functions

Scope of use of Java custom annotations?

Some repetitive logic can be realized through annotations, just like an encapsulated method, which can be used in some permission verification, field verification, field attribute injection, log saving and caching.

Next, let's understand the functions of the four annotations in the meta annotation

@Target: used to describe the scope of the annotation and where the annotation is used
For example, @ Target (ElementRType.METHOD) | indicates that the annotation is used on the method. If the annotation is marked on the class, an error will be reported.
@Retention: indicates the lifecycle of the annotation
For example, @ Retention(RetentionPolicy.RUNTIME) | is loaded by the JVM and contained in the class file, which can be obtained at run time
@Inherited: is a tag annotation. Adding this annotation indicates that the marked type can be inherited. If one is used @If the annotation type of Inherited modifier is used for a class, then this annotation will be used for subclasses of this class.
@Documented: indicates that the element marked by the annotation can be documented by Javadoc or similar tools.

Basic elements for creating annotations

1. The access modifier must be public. If it is not written, it is public by default

2. Keyword for creating annotation: @ interface

Implementation steps of meta annotation

1. First, you need to create an annotation using the @ interface keyword

2. Create an AOP aspect to intercept the annotation, intercept the methods using the annotation, obtain the requestParam parameter above the annotation, and verify whether the required attributes exist

Demo to implement meta annotation

1. Create annotation

package com.nanfeng.annotations.anno;

/**
 * @Retention Is an annotation of an annotation, called a meta annotation of an annotation
 */

import java.lang.annotation.*;

@Target({ElementType.METHOD}) //Mark that the annotation acts on the method
@Retention(RetentionPolicy.RUNTIME) //Valid at runtime
public @interface RequestLog {
    /**
     *Attribute values can be customized in annotations
     * If the method defined in the annotation has no return value, it will return the default value of the attribute in our annotation
     * Later, we need to get some parameters on the annotation, and get the default value without
     */
    String[] value() default "South wind"; // For example, the default value is "south wind". If the parameter on the annotation does not get this parameter, it will return to south wind

}

2. Create an AOP slice

package com.nanfeng.annotations.aspect;

import com.nanfeng.annotations.anno.RequestLog;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
@Order(0) //Defines the priority of the execution order of beans in the Spring IOC container. The smaller the number, the higher the priority
public class RequestLogAspect {


    /**
     * The first * indicates any type of matching return value; You can also specify matching fixed return value types
     * com.nanfeng.annotations.controller Indicates that the pointcut intercepts the classes under the controller package and does not intercept other packages
     * ..Indicates the current and below,.. * indicates that all sub packets below the current match
     * (..)Represents any method name, parentheses represent parameters, and two points represent any parameter type
     */
    @Pointcut("execution(* com.nanfeng.annotations.controller..*(..))")
    public void pointCut() {

    }

    /**
     * @Around("pointCut() && @annotation(requestLog)") : It indicates that the method that matches the class path that satisfies the definition of pointCut() and is marked with @ RequestLog annotation will enter this aspect
     */
    @Around("pointCut() && @annotation(requestLog)")
    public Object arround(ProceedingJoinPoint point, RequestLog requestLog) {
        // Save the value returned by the original method
        Object o = null;
        try {
            //Gets the request input parameter of the method
            Object[] requestParam = point.getArgs();
            //Gets the name of the executed method
            String runMethodName=point.getSignature().getDeclaringTypeName();
            //Get the current request, through which you can get the url address to access the request
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            String sessionId = attributes.getSessionId();
            HttpServletRequest request = attributes.getRequest();
            //Gets the api path of the request
            String url = request.getRequestURL().toString();

            String[] value = requestLog.value();//Get the parameters in the annotation
            o = point.proceed();//The return value is the return value of the original method
            return o;//Call the proceed method of the pointcut to indicate release
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return o;//Call the proceed method of the pointcut to indicate release
    }
}

3. Create entities for testing

package com.nanfeng.annotations.entity;

public class User {

    private String name; // full name
    private String address; // address
    private String number; // number

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", number='" + number + '\'' +
                '}';
    }
}

Controller layer

package com.nanfeng.annotations.controller;


import com.nanfeng.annotations.anno.RequestLog;
import com.nanfeng.annotations.entity.User;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class indexController {



    @PostMapping("/test")
    @RequestLog
    public String test(@RequestBody User user){
        return user.toString();
    }
}

Test with postman

 

Keywords: Java Eclipse Algorithm

Added by jerastraub on Mon, 22 Nov 2021 23:38:11 +0200