Define an Annotation class
Annotation in Chinese means Annotation. The specific meaning of Annotation can be found in the rookie tutorial. On this annotation class, there are three annotations: @target, @Retention, and @Documented. Click on any annotation in Springboot (@Controller, @Service, etc.) and you will see that all three annotations appear all the time. All annotations need to be added.
import java.lang.annotation.*;
/** * TYPE means it can be placed on a class, MTTHOD means it can be placed on a method */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {
String module(a) default "";
String operator(a) default "";
}
Copy the code
2. Define the Aspect class Aspect
- With the annotations declared, we need to define a facet class that implements all the operations we need. Add the @pointcut Annotation to the pt() function to represent the Pointcut, containing the package address of the @annotation you just declared.
- Define the log function and add the @around annotation Around the pt() function.
import com.alibaba.fastjson.JSON;
import com.jyuxuan.blog.utils.HttpContextUtils;
import com.jyuxuan.blog.utils.IPUtils;
import lombok.extern.slf4j.Slf4j;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
@Component
@Aspect // The section defines the relationship between the notification and the pointcut
@Slf4j
public class LogAspect {
@Pointcut("@annotation(com.***.blog.common.aop.LogAnnotation)")
public void pt(a) {}/** * wrap around notification */
@Around("pt()")
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
long beginTime = System.currentTimeMillis();
// Execute method
Object result = joinPoint.proceed();
// Execution time (ms)
long time = System.currentTimeMillis() - beginTime;
// Save the log
recordLog(joinPoint, time);
return result;
}
private void recordLog(ProceedingJoinPoint joinPoint, long time) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
log.info("=====================log start================================");
log.info("module:{}", logAnnotation.module());
log.info("operation:{}", logAnnotation.operator());
// The method name of the request
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
log.info("request method:{}", className + "." + methodName + "()");
// Request parameters
Object[] args = joinPoint.getArgs();
String params = JSON.toJSONString(args[0]);
log.info("params:{}", params);
// Get request set IP address
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
log.info("ip:{}", IPUtils.getIpAddr(request));
log.info("excute time : {} ms", time);
log.info("=====================log end================================"); }}Copy the code
3. Use annotations in the Controller method
Add annotations to one of your random methods to view the log information on the workbench.
@PostMapping
@logAnnotation (Module = "name ", operator =" operation name ")
public Result test(@RequestBody Work work) {
return Result.success(null);
}
Copy the code
4. Supplementary content
1. @ Target
Click on any annotation to see the @target annotation, then click on the @target annotation to find the following. Click ElementType again
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
Copy the code
Here you can see all the content information that @target can annotate, all in the comment.
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE, // Class, interface, or enumeration
/** Field declaration (includes enum constants) */
FIELD, / / domain
/** Method declaration */
METHOD, / / method
/** Formal parameter declaration */
PARAMETER, / / parameters
/** Constructor declaration */
CONSTRUCTOR, // constructor
/** Local variable declaration */
LOCAL_VARIABLE, // Local variables
/** Annotation type declaration */
ANNOTATION_TYPE, // Annotation type
/** Package declaration */
PACKAGE, / / package
/**
* Type parameter declaration
*
* @since1.8 * /
TYPE_PARAMETER, // Parameter type
/**
* Use of a type
*
* @since1.8 * /
TYPE_USE // Can mark any type
}
Copy the code
2, @ Retention
Specify the lifetime of the modified annotations, that is, to which stage they will remain, by clicking enter.
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value(a);
}
Copy the code
Click RetentionPolicy again.
public enum RetentionPolicy {
/** * Annotations are to be discarded by the compiler. */
SOURCE, // indicates that the source level is reserved and lost after compilation
/** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */
CLASS, // Compile-level reserved, present in the compiled class file, discarded at JVM runtime, (default)
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME // The runtime level is reserved, which exists in the compiled class file and is retained at JVM runtime and can be called by reflection
}
Copy the code
3, @ Documented
Indicates that the annotation is recorded by Javadoc, indicating that the class under the annotation appears in the Java Doc HTML document.
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
Copy the code