java自定义注解学习(三)_注解解析及应用
上篇文章已经介绍了注解的基本构成信息。这篇文章,主要介绍注解的解析。毕竟你只声明了注解,是没有用的。需要进行解析。主要就是利用反射机制在运行时进行查看和利用这些信息
常用方法汇总
在Class、Field、Method、Constructor中都有如下方法:
//获取所有的注解 public Annotation[] getAnnotations() //获取所有本元素上直接声明的注解,忽略inherited来的 public Annotation[] getDeclaredAnnotations() //获取指定类型的注解,没有返回null public <A extends Annotation> A getAnnotation(Class<A> annotationClass) //判断是否有指定类型的注解 public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
Annotation 是一个借口,它表示注解,源码为:
public interface Annotation { boolean equals(Object obj); int hashCode(); String toString(); //返回真正的注解类型 Class<? extends Annotation> annotationType(); }
实际上,所有的注解类型、内部实现时,都是扩展的Annotation
对于Method和Contructor,他们都有方法参数
public Annotation[][] getParameterAnnotations()
应用注解
日常工作中,每个公司都会自定义注解进行记录日志的,我们就做一个简单的记录日志操作的注解,结合aop和springboot
1.建立springboot项目
这里不再赘述,主要需要引入aop
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
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 @Component public 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; @RestController public class HelloController { @RequestMapping(value = "/hello") @KevinLog("kevin test !") public String hello() { return "hello kevin"; } }
5.启动测试
访问:http://localhost:8080/hello
页面出现: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=7 2018-10-22 10:38:22.456 INFO 3916 --- [nio-8080-exec-2] com.kevin.anno.aspect.LogAscpect : url=http://localhost:8080/hello 2018-10-22 10:38:22.456 INFO 3916 --- [nio-8080-exec-2] com.kevin.anno.aspect.LogAscpect : method = GET 2018-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:1 2018-10-22 10:38:22.457 INFO 3916 --- [nio-8080-exec-2] com.kevin.anno.aspect.LogAscpect : class_method=com.kevin.anno.controller.HelloController.hello 2018-10-22 10:38:22.457 INFO 3916 --- [nio-8080-exec-2] com.kevin.anno.aspect.LogAscpect : args = {}
总结
其实, 大家可以自己写这玩玩,比较这个demo还用到了aop,工作中很少接触到aop。以至于面试的时候,问你aop的时候,自己都没有实际的应用过。
好了。玩的开心!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
java自定义注解学习(二)_注解详解
上篇文章,我们简单的实现了一个自定义注解,相信大家对自定义注解有了个简单的认识,这篇,这样介绍下注解中的元注解和内置注解 整体图示 内置注解 @Override 重写覆盖 这个注解大家应该经常用到,主要在子类重写父类的方法,比如toString()方法 package com.kevin.demo; public class Demo1 { @Override public String toString(){ return "demo1"; } } @Deprecated 过时 @Deprecated可以修饰的范围很广,包括类、方法、字段、参数等,它表示对应的代码已经过时了,程序员不应该使用它,不过,它是一种警告,而不是强制性的。 package com.kevin.demo; public class Demo1 { @Deprecated public void goHome(){ System.out.println("过时的方法"); } } idea中调用这些方法,编译器也会显示删除线并警告 @SuppressWarning 压制Java的编译警告 @SuppressWar...
- 下一篇
教你搭建个人/企业私有云盘-kodexplorer
环境说明: 系统版本:CentOS 6.9 x86_64 软件版本:nginx-1.12.2php-5.5.38 可道云kodexplorer4.37 1、nginx的编译安装 1.1 创建目录mkdir -p /service/toolsmkdir /applicationcd /service/toolswget http://nginx.org/download/nginx-1.12.2.tar.gz 下载或者上传nginx包 1.2 解压tar zxvf nginx-1.12.2.tar.gz 1.3 编译安装yum install gcc gcc-c++ glibc -y #安装编译器yum install pcre-devel zlib-devel openssl-devel –y 装pcre为了重写rewrite提供正则表达式库,装zlib为了gzip提供数据压缩用的函数库,装openssl为 Nginx 模块(如 ssl )提供密码算法、证书以及 SSL 协议等功能C语言源码包,需要编译才能使用编译安装三部曲 ./configure(指定编译参数:安装目录及版本) cd...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS关闭SELinux安全模块
- 2048小游戏-低调大师作品
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程