注解-Annotation解析

1 篇文章 0 订阅

一、概念

        注解是一种关联元程序中元素信息与元数据的方法和途径。Annotation程序可以通过Java的反射机制来获取程序中元素的Annotation对象,通过Annotation对象则可以获取到注解中的元数据信息。

二、元注解

        元注解用于注解其他注解,以下是四种标准元注解:

        1、@Target注解定义Annatation修饰对象的作用范围

             可被用于packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(成员变量、catch变量)。在Annotation中使用了Target,可更明晰其修饰目标。参数如下:

  • TYPE : 类、接口或enum声明
  • FIELD: 域(属性)声明
  • METHOD: 方法声明
  • PARAMETER: 参数声明
  • CONSTRUCTOR: 构造方法声明 LOCAL_VARIABLE:局部变量声明
  • ANNOTATION_TYPE:注释类型声明
  • PACKAGE: 包声明

        2、@Retention定义Annotation被保留的时间长短

              定义注解信息保存的级别,描述注解的生命周期。取值如下:

  • SOURCE:在源文件中有(源文件保留)
  • CLASS:在Class中有效(Class保留)
  • RUNTIME:在运行时有效(运行时有效)

        3、@Documented 描述Java-doc

              用于描述其它类型的 Annotation 中应该被标注的程序成员的公共 API,因此可以被javadoc 此类的工具文档化。

        3、@Inherited 阐述被标注的类型是被继承的

              如果一 个使用了@Inherited Annotation 类型被用于一个 class,则这个 annotation 将被用于该 class 的子类,但是@Inherited  修饰接口时不可继承。

三、注解处理器

        注解处理器用于处理Annotation,使注解生效,产生预期效果。

四、自定义注解实现 

        1、自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SysLog {

    /**
     * 操作模块
     */
    String module() default "";

    /**
     * 操作内容
     */
    String operation() default "";

    /**
     * 不记录返回值,默认false,记录返回值。
     */
    boolean ignoreResponse() default false;

    /**
     * 不记录的参数,默认全记录。配置参数名称。
     */
    String[] ignoreParameters() default {};

}

        2、自定义注解处理器

@Slf4j
@Aspect
@Component
public class SysLogAspect {、

    private ObjectMapper mapper = new ObjectMapper();

    /**
     * 异步记录日志
     */
    private static ExecutorService logExecutorService = Executors.newSingleThreadExecutor();
    
    // 定义自定义注解为切点
    @Pointcut("@annotation(com.example.demo.study.SysLog)")
    public void logPointCut() {

    }

    @AfterReturning(pointcut = "logPointCut()", returning = "response")
    public void saveSysLog(JoinPoint joinPoint, Object response) {
        // The method of obtaining the weaving point from the cut in point by reflection mechanism
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        // 获取请求类名
        String className = joinPoint.getTarget().getClass().getName();
        // 获取请求方法名
        String methodName = method.getName();
        methodName = className + "." + methodName;

        String operation = null;
        // 获取注解信息
		SysLog sysLog = method.getAnnotation(SysLog.class);
        // 注解中操作属性
        if (sysLog != null) {
            operation = "[" + sysLog.module() + "]" + sysLog.operation();
        }

        // 参数信息
        StringJoiner sjArgsInfo = new StringJoiner(",");
        Parameter[] parameters = method.getParameters();
        Object[] args = joinPoint.getArgs();

        outer:
        for (int i = 0; i < args.length; i++) {
            try {
                String paramName = parameters[i].getName();
                if (sysLog != null) {
                    String[] ignoreParameters = sysLog.ignoreParameters();
                    if (ignoreParameters.length > 0) {
                        for (String ignore : ignoreParameters) {
                            if (paramName.equals(ignore)) {
                                continue outer;
                            }
                        }
                    }
                }
                String argInfo = null;
                if (sysLog != null && "toString".equalsIgnoreCase(sysLog.serializationType())) {
                    argInfo = args[i].toString();
                } else {
                    argInfo = mapper.writeValueAsString(args[i]);
                }
                sjArgsInfo.add(paramName + ":" + argInfo);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        // 返回信息
        String returnInfo = null;
        if (sysLog != null && !sysLog.ignoreResponse()) {
            try {
                if (sysLog != null && "toString".equalsIgnoreCase(sysLog.serializationType())) {
                    returnInfo = response.toString();
                } else {
                    returnInfo = mapper.writeValueAsString(response);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        /**
         * 处理注解信息
         * 可用于写文件或者存数据库
         */
    }
}

3、自定义注解使用方式

@SysLog(module = "模块名",operation = "操作内容",ignoreParameters = "忽略的参数",ignoreResponse = true)
@PostMapping("/user/login")
public UserRequest login(@RequestBody User user) {
     System.out.println(user);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值