springboot自定义注解
springboot自定义注解常见的应用就是在自定义记录操作日志、自定义数据字典等操作上面。自定义注解一般是搭配aop使用的。要学习自定义注解
创建注解
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented //生成文档
public @interface OpreatorLog {
/**
* 日志描述,没有默认值,使用注解的时候必须给operateDec参数赋值
*/
String operateDec();
/**
* 日志类型,默认值为2
* 1:登录日志;2:操作日志;3:定时任务;
*/
int logType() default 2;
}
- 注解定义为@interface, 所有的注解会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口
- 参数成员只能用public或默认(default)这两个访问权修饰
- 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组
- @Target注解:指明了修饰的这个注解的使用范围,也就是注解可以用在哪里。ElementType的取值包含以下几种
- TYPE:类,接口或者枚举
- FIELD:域,包含枚举常量
- METHOD:方法(我们用这个)
- PARAMETER:参数
- CONSTRUCTOR:构造方法
- LOCAL_VARIABLE:局部变量
- ANNOTATION_TYPE:注解类型
- PACKAGE:包
- @Retention注解:指明修饰的注解的生存周期,注解在哪个阶段执行。RetentionPolicy的取值包含以下三种
- SOURCE:源码级别保留,编译后即丢弃。
- CLASS: 编译级别保留,编译后的class文件中存在,在jvm运行时丢弃,这是默认值。
- RUNTIME: 运行级别保留,编译后的class文件中存在,在jvm运行时保留,可以被反射调用。(我们用这个)
- @Documented:它代表着此注解会被javadoc工具提取成文档
- 注解里面可以有多个成员变量,可以通过default给成员变量一个默认值,如果没有默认值,那么在使用该注解的时候必须给这个成员变量赋值
创建切面
创建OperatorLogAspect
,代码如下
@Aspect
@Component
public class OperatorLogAspect {
/**
* 定义切点Pointcut
*/
@Pointcut("execution(public * com.moyundong..*.*Controller.*(..))")
public void excudeService() {
}
/**
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("excudeService()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
//从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//获取切入点所在的方法
Method method = signature.getMethod();
//获取操作,如果有注解,就执行增加日志操作
OpreatorLog myLog = method.getAnnotation(OpreatorLog.class);
if (myLog != null) {
//操作类型
int logType = myLog.logType();
String operateDec = myLog.operateDec();
//获取请求的类名
String className = joinPoint.getTarget().getClass().getName();
//获取请求的方法名
String methodName = method.getName();
System.out.println("logType="+logType);
System.out.println("operateDec="+operateDec);
System.out.println("className="+className);
System.out.println("methodName="+methodName);
// ......
// 做你想做的任何事情
}
return joinPoint.proceed();
}
}
使用自定义注解
我们创建一个测试类,在类的方法上面加自定义注解@OpreatorLog
,因为operateDec没有默认值,所以必须赋值。logType有默认值,所以可以不输入。
/**
* @Description: 测试类
**/
@RestController
@RequestMapping("test")
public class TestController {
@RequestMapping("add")
@OpreatorLog(operateDec = "这是一个添加任务")
public String add(){
return "添加成功 !";
}
@RequestMapping("edit")
@OpreatorLog(operateDec = "这是一个修改任务")
public String edit(){
return "修改成功 !";
}
@RequestMapping("delete")
@OpreatorLog(operateDec = "这是一个删除任务")
public String delete(){
return "删除成功 !";
}
@RequestMapping("login")
@OpreatorLog(operateDec = "这是一个登录任务",logType = 1)
public String login(){
return "登录成功 !";
}
}
测试
项目启动后,在浏览器输入http://localhost:8088/moyundong/test/login
和http://localhost:8088/moyundong/test/add
会得到如下信息
logType=1
operateDec=这是一个登录任务
className=com.moyundong.controller.TestController
methodName=login
logType=2
operateDec=这是一个添加任务
className=com.moyundong.controller.TestController
methodName=add
::: tip 提示
本节内容只是讲了自定义注解的基本原理,后面我们会讲解springboot基于注解的操作日志
:::