自定义注解
注解是什么?
注解(Annotation)也叫元数据,用于对代码进行说明,可以对包、类、接口、字段、方法参数、局部变量等进行注解。其实说白就是代码里的特殊标志,这些标志可以在编译,类加载,运行时被读取,并根据这些信息执行相应的处理,以便于其他工具补充信息或者进行部署。
元数据(Metadata),又称中介数据、中继数据,为描述数据的数据(data about data),主要是描述数据属性(property)的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等功能。
如果说注释是写给人看的,那么注解就是写给程序看的。它更像一个标签,贴在一个类、一个方法或者字段上。它的目的是为当前读取该注解的程序提供判断依据。比如程序只要读到加了@Test的方法,就知道该方法是待测试方法,又比如@Before注解,程序看到这个注解,就知道该方法要放在@Test方法之前执行。
注解类型
@Target(标明注解使用的范围)
“@Target(ElementType.TYPE):作用接口、类、枚举、注解 @Target(ElementType.FIELD) :作用属性字段、枚举的常量 @Target(ElementType.METHOD):作用方法 @Target(ElementType.PARAMETER):作用方法参数
”
@Retention(标明注解被保留的阶段)
“@Retention(RetentionPolicy.SOURCE) 注解仅存在于源码中,在class字节码文件中不包含 @Retention(RetentionPolicy.CLASS) 默认的策略,在class字节码文件中存在,但运行时无法获得 @Retention(RetentionPolicy.RUNTIME) 在class字节码文件中存在,在运行时可以通过反射获取到
”
@Documented(标明是否生成javadoc文档)
@Inherited(标明注解可继承)
举个栗子
创建注解
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SysLog {
//模块
String model();
//方法名称
String name();
//功能code
String[] code();
}
AOP处理注解
@Component
@Aspect
@Slf4j
public class SysLogAspect {
@Pointcut("@annotation(com.example.demo.annotation.SysLog)")
public void logPoint(){}
@Around("logPoint()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable{
Object result = null;
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null){
SysLog sysLog = method.getAnnotation(SysLog.class);
String[] code = sysLog.code();
String name = sysLog.name();
String model = sysLog.model();
Object proceed = joinPoint.proceed();
log.info("code = {},name={},model={},proceed={}",code,name,model,proceed);
return proceed;
}
return result;
}
}
使用注解
@RestController
public class UserController {
@SysLog(model = "用户模块", name = "getUserName", code = {"c","r","u","d"})
@GetMapping("/userName")
public void getUserName(String userName){
return userName;
}
}
AOP中log日志打印结果
“code = [c, r, u, d],name=getUserName,model=用户模块,proceed=liugui
”