前言
大家在学习Spring
框架时都一定深入理解并实现了它两个强大的特性,AOP
(面向切面)和IOC
(控制反转),其中在学习AOP
时大家最常见的就是利用切面进行日志记录(每次面试时只要问道Spring一定有AOP,提及AOP一定有日志记录)。接下来我们通过一个小Demo看看如何通过自定义注解的方式添加日志记录。
Spring Boot实现自定义注解
依赖引入
首先,我们创建一个Spring Boot项目,添加maven依赖spring-boot-starter-aop
,spring-boot-starter-aop
模块自身提供了针对 spring-aop
、aspectjrt
和 aspectjweaver
的依赖,包含了我们实现自定义注解的所有功能。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
自定义注解
第一步,我们创建我们需要自定义的注解@SaveSystemLog
,这是一个方法级别的注解,用于标注我们需要监控的方法。我们先来创建自定义注解类SaveSystemLog
import java.lang.annotation.*;
/**
* 定义一个方法级别的@SaveSystemLog注解,用于标注需要监控的方法:
* @author Administrator
*/
@Target(ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
public @interface SaveSystemLog {
/**
* 操作名称
*/
String value() default "";
/**
* 日志类别
*/
String type() default "1";
}
第二步,创建切面实现类SystemLogAspect
,
public class SystemLogAspect {
@Pointcut("execution(* com.tyaa.client.controller.*.*(..)) && @annotation(com.tyaa.client.annotation.SaveSystemLog)")
public void pointcut() {
}
@Around("pointcut()")
public Object around(ProceedingJoinPoint point) {
Object result = null;
long beginTime = System.currentTimeMillis();
try {
// 执行方法
result = point.proceed();
} catch (Throwable e) {
log.error(e.getMessage());
}
// 执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
// 保存日志
saveLog(point, time);
return result;
}
private void saveLog(ProceedingJoinPoint joinPoint, long time) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
SaveSystemLog logAnnotation = method.getAnnotation(SaveSystemLog.class);
System.out.println("日志保存成功:"+logAnnotation.value());
}
}
最后,我们写一个测试方法,在方法上面加上我们的自定义注解@SaveSystemLog
,然后运行看下结果。
public class Test1 {
@RequestMapping("/log")
@SaveSystemLog(value = "测试日志")
public void saveLog(){
System.out.println("123");
}
}
可以看到,我们的自定义注解已经生效,这样接下来的开发中我们只要在方法上加上该注解就能实现日志记录的切面功能的。
功能介绍
上面的demo中我们可以看到,在实现自定义注解功能时,我们在注解类上添加了@Target
和@Retention
这两个注解。那么这两个注解有什么作用呢,我们一一看下。首先是@Target
注解,他的作用是将这个注解放在什么地方,比如类上、方法上、构造器上、变量上等,他的值是一个枚举类型的。我们在demo中使用的是ElementType.METHOD
,即用于描述方法。然后是 @Retention
注解,它的作用是为了说明这个注解的生命周期,也可以说是注解的保留位置。在注解中有三个生命周期,即
- RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
- RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
- RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
总结
相信通过上面的一个简单Demo,大家应该学到了怎样创建一个自定义注解,希望这种方式能够给大家的开发给来一定帮助。后面的更文会介绍Spring Boot的一些其他知识点,希望大家能够能够学到一些新的东西。