Annotation作用
它不是程序本身,可以对程序作出标识(实际的操作依据业务的需求对注解做行为,如日志记录)。(类似于注释)可以被其他程序(如编译器等)读取。而注解的实现是通过反射机制来完成
Annotation使用范围
在package, class, method, field等上面,相当于给它们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问
元注解
元注解的作用就是负责注解其他注解。Java定义了 4个标准的meta-annotation类型,它们被用来提供对其它annotation类型作说明
@Target
用于描述注解的使用范围
@Retention
表示需要在什么级别保存该注释信息,用于描述注解的生命周期
@Documented
@Inherited
被它修饰的annotation具有继承性。如果某个类使用了被@inherited修饰的注解,则其子类将自动具有该注解
自定义注解
使用@interface自定义注解时,自动继承了Annotation接口
要点:
- @interface用来声明一个注解
格式为: public @interface注解名{定义体} - 其中的每一 个方法实际上是声明了一个配置参数
方法的名称就是参数的名称
返回值类型就是参数的类型(返回值类型只能是基本类型、Class、 String、enum)
可以通过default来声明参数的默认值
如果只有一个参数成员,一般参数名为value
@Target({METHOD})
@Retention(RUNTIME)
@Documented
public @interface LogAnnotation {
String module() default "";
String operator() default "";
}
使用:
@LogAnnotation(module = "文章",operator = "获取文章列表")
#aop的实现
@Component
@Aspect
@Slf4j
public class LogAop {
@Pointcut("@annotation(com.design.blog.aop.LogAnno)")
public void pt(){}
@Around("pt()")
public Object Log(ProceedingJoinPoint joinPoint) throws Throwable {
long begin = System.currentTimeMillis();
Object result = joinPoint.proceed();
long end = System.currentTimeMillis();
RecordLog(joinPoint, (end - begin));
return result;
}
private void RecordLog(ProceedingJoinPoint joinPoint, long time) {
//获取方法切点的标识信息
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method = signature.getMethod();
LogAnno annotation = method.getAnnotation(LogAnno.class);
//获取注解参数
String module = annotation.module();
String operator = annotation.operator();
log.info("==============log-start================");
log.info("request模块:{}",module);
log.info("request方法:{}",operator);
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
log.info("request method{}",className+"."+methodName+"()");
Object[] args = joinPoint.getArgs();
String params = JSON.toJSONString(args[0]);
log.info("request参数:{}",params);
log.info("request时长:{}毫秒", time);
log.info("=============log-end===================");
}
}