博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java自定义注解学习(三)_注解解析及应用
阅读量:6045 次
发布时间:2019-06-20

本文共 4849 字,大约阅读时间需要 16 分钟。

上篇文章已经介绍了注解的基本构成信息。这篇文章,主要介绍注解的解析。毕竟你只声明了注解,是没有用的。需要进行解析。主要就是利用反射机制在运行时进行查看和利用这些信息

常用方法汇总

在Class、Field、Method、Constructor中都有如下方法:

//获取所有的注解public Annotation[] getAnnotations()//获取所有本元素上直接声明的注解,忽略inherited来的public Annotation[] getDeclaredAnnotations()//获取指定类型的注解,没有返回nullpublic  A getAnnotation(Class annotationClass)//判断是否有指定类型的注解public boolean isAnnotationPresent(Class
annotationClass)

Annotation 是一个借口,它表示注解,源码为:

public interface Annotation {    boolean equals(Object obj);    int hashCode();    String toString();    //返回真正的注解类型    Class
annotationType();}

实际上,所有的注解类型、内部实现时,都是扩展的Annotation

对于Method和Contructor,他们都有方法参数

public Annotation[][] getParameterAnnotations()

应用注解

日常工作中,每个公司都会自定义注解进行记录日志的,我们就做一个简单的记录日志操作的注解,结合aop和springboot

1.建立springboot项目

这里不再赘述,主要需要引入aop

org.springframework.boot
spring-boot-starter-aop

2.定义自定义注解

package com.kevin.anno.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface KevinLog {    String value() default "";}

3.定义aspect及解析注解

package com.kevin.anno.aspect;import com.kevin.anno.annotation.KevinLog;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;import java.lang.reflect.Method;@Aspect@Componentpublic class LogAscpect {    private final static Logger logger = LoggerFactory.getLogger(LogAscpect.class);    @Pointcut("@annotation(com.kevin.anno.annotation.KevinLog)")    public void log() {    }    @Around("log()")    public Object aroundAdvice(ProceedingJoinPoint point) throws Throwable {        Object object = null;        long start = System.currentTimeMillis();        Method method = ((MethodSignature) MethodSignature.class.cast(point.getSignature())).getMethod();        KevinLog kevinLog = method.getAnnotation(KevinLog.class);        String operationName = kevinLog.value();        object = point.proceed(point.getArgs());        long end = System.currentTimeMillis();        Long excuteTime = end - start;        print(operationName, excuteTime, point);        return object;    }    private void print(String operationName, Long excuteTime, ProceedingJoinPoint point) {        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();        HttpServletRequest request = attributes.getRequest();        //operationName        logger.info("operationName={}", operationName);        //time        logger.info("time={}", excuteTime);        // url        logger.info("url={}", request.getRequestURL());        //method        logger.info("method = {}", request.getMethod());        //ip        logger.info("ip = {}", request.getRemoteAddr());        //类方法        logger.info("class_method={}", point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName());        //参数        logger.info("args = {}", point.getArgs());    }}

4. 在请求方法上加上自定义注解

package com.kevin.anno.controller;import com.kevin.anno.annotation.KevinLog;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class HelloController {    @RequestMapping(value = "/hello")    @KevinLog("kevin test !")    public String hello() {        return "hello kevin";    }}

5.启动测试

访问:

页面出现:hello kevin

控制台打印信息如下:

2018-10-22 10:38:22.456  INFO 3916 --- [nio-8080-exec-2] com.kevin.anno         : operationName=kevin test !2018-10-22 10:38:22.456  INFO 3916 --- [nio-8080-exec-2] com.kevin.anno.aspect.LogAscpect         : time=72018-10-22 10:38:22.456  INFO 3916 --- [nio-8080-exec-2] com.kevin.anno.aspect.LogAscpect         : url=http://localhost:8080/hello2018-10-22 10:38:22.456  INFO 3916 --- [nio-8080-exec-2] com.kevin.anno.aspect.LogAscpect         : method = GET2018-10-22 10:38:22.457  INFO 3916 --- [nio-8080-exec-2] com.kevin.anno.aspect.LogAscpect         : ip = 0:0:0:0:0:0:0:12018-10-22 10:38:22.457  INFO 3916 --- [nio-8080-exec-2] com.kevin.anno.aspect.LogAscpect         : class_method=com.kevin.anno.controller.HelloController.hello2018-10-22 10:38:22.457  INFO 3916 --- [nio-8080-exec-2] com.kevin.anno.aspect.LogAscpect         : args = {}

总结

其实, 大家可以自己写这玩玩,比较这个demo还用到了aop,工作中很少接触到aop。以至于面试的时候,问你aop的时候,自己都没有实际的应用过。

好了。玩的开心!

转载地址:http://ijiex.baihongyu.com/

你可能感兴趣的文章
Ztree异步加载自动展开节点
查看>>
反射操作公共成员变量
查看>>
Android热修复升级探索——代码修复冷启动方案
查看>>
学校宿舍的深夜之思考
查看>>
字符串的扩展
查看>>
神奇语言 python 初识函数
查看>>
Windows安装Composer出现【Composer Security Warning】警告
查看>>
企业架构研究总结(22)——TOGAF架构开发方法(ADM)之信息系统架构阶段
查看>>
linux
查看>>
[Hadoop]MapReduce多输出
查看>>
算法(Algorithms)第4版 练习 1.3.4
查看>>
jquery easyUI checkbox复选项获取并传后台
查看>>
浅析NopCommerce的多语言方案
查看>>
设计模式之简单工厂模式
查看>>
C++中变量的持续性、链接性和作用域详解
查看>>
2017 4月5日上午
查看>>
第一阶段冲刺报告(一)
查看>>
使用crontab调度任务
查看>>
【转载】SQL经验小记
查看>>
zookeeper集群搭建 docker+zk集群搭建
查看>>