会使用自定义注解 ≈ 好的程序员?教你结合 AOP 切面打印请求日志

========================================================================

3.1 概念

====================================================================

知其然,要知其所以然,所以我们先来康康官方对注解的描述是什么:

An annotation is a form of metadata, that can be added to Java source code. Classes, methods, variables, parameters and packages may be annotated. Annotations have no direct effect on the operation of the code they annotate.

翻译过来的大意是:

注释是一种元数据的形式,可以添加到Java源代码中。类,方法,变量,参数和包可以注释。注释对他们注释的代码的操作没有直接影响。

综上来说,注解其实相当于 Java 的一种特殊的数据类型,也可以把它当做一个可以自定义的标记去理解,和类、接口、枚举类似,可以使用在很多不同的地方并且对原有的操作代码没有任何影响,仅做中间收集和处理。

3.2 小试牛刀

======================================================================

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.FIELD)

public @interface Excel {

public String name();

int sort() default Integer.MAX_VALUE;

… …

}

说明(从上往下):

  • 使用该注解在程序运行时被 JVM 保留,并且被编译器记录到 class 文件中,所以能够通过 Java 反射机制读取到注解中的属性等

  • 该注解仅能使用在字段上,不能用在类、方法、变量上

  • 该注解有两个属性,一个是 name 另一个是 sort 属性,属性?你可能就会问了后边不是带一对圆括号嘛,不应该是方法吗?看似接口中定义的抽象方法,实则看没看到 default 关键字,官方管定义在注解内的是 注解类型元素 ,不过我习惯管它们叫属性,因为在使用注解时,总是以键值对的形式传参

  • 访问修饰符必须为 public,不写默认为 public

  • 圆括号不是定义方法参数的地方,也不能在括号中定义任何参数,这仅仅是一个特殊的写法罢了

  • default 表示未设置该属性时的默认值,值需和类型保持一致

  • 如果没有 default 默认值,表示该类型元素必须在后续赋值

3.3 注解注解的注解类

==========================================================================

此外,在 JDK 中提供了 4 个标准的用来对注解类型进行注解的注解类(元注解),分别是:

  • @Target 是专门用来限定某个自定义注解能够被应用在哪些 Java 元素上

public enum ElementType {

/** Class, interface (including annotation type), or enum declaration */

/** 类,接口(包括注释类型)或枚举声明 */

TYPE,

/** Field declaration (includes enum constants) */

/** 字段声明(包括枚举常量) */

FIELD,

/** Method declaration */

/** 方法声明 */

METHOD,

/** Formal parameter declaration */

/** 形参声明 */

PARAMETER,

/** Constructor declaration */

/** 构造器声明 */

CONSTRUCTOR,

/** Local variable declaration */

/** 本地变量声明 */

LOCAL_VARIABLE,

/** Annotation type declaration */

/** 注解类型声明 */

ANNOTATION_TYPE,

/** Package declaration */

/** 包声明 */

PACKAGE,

/**

  • Type parameter declaration

  • @since 1.8

*/

/** 类型参数声明 */

TYPE_PARAMETER,

/**

  • Use of a type

  • @since 1.8

*/

/** 使用类型 */

TYPE_USE

}

  • @Retention 该注解有 “保留”、“保持” 之义,用来定义注解的留存策略,可指定的留存策略只有 3 个:

public enum RetentionPolicy {

/**

  • Annotations are to be discarded by the compiler.

  • 编译器丢弃注解,即被编译器忽略

*/

SOURCE,

/**

  • Annotations are to be recorded in the class file by the compiler

  • but need not be retained by the VM at run time. This is the default

  • behavior.

  • 注释将被编译器记录在 class 文件中,但在运行时不需要被虚拟机保留。这是一个默认的行为。

*/

CLASS,

/**

  • Annotations are to be recorded in the class file by the compiler and

  • retained by the VM at run time, so they may be read reflectively.

  • 注释将由编译器记录在类文件中,并在运行时由虚拟机保留,因此可以通过反射读取。

  • @see java.lang.reflect.AnnotatedElement

*/

RUNTIME

}

一般使用无特殊需要,使用 RetentionPolicy.RUNTIME 就够了。

  • @Documented 是被用来指定自定义注解是否能随着被定义的 Java 文件生成到 JavaDoc 文档当中

  • @Inherited 是指定某个自定义注解如果写在了父类的声明部分,那么子类的声明部分也能自动拥有该注解

注意:@Inherited 注解只对那些 @Target 被定义为 ElementType.TYPE 的自定义注解起作用。

3.4 使用流程

======================================================================

image.gif

四、代码实现

====================================================================

4.1 第一步

=====================================================================

编写设计注解:

/**

  • @description: TODO

  • @author: HUALEI

  • @date: 2021-11-19

  • @time: 15:50

*/

@Retention(RetentionPolicy.RUNTIME)

/* 注解用在方法上 */

@Target(ElementType.METHOD)

public @interface MyAnnotation {

/**

  • 接口方法描述

*/

public String description() default “默认描述”;

}

这步没什么好讲的,上面的概念理解掌握了,轻轻松松写出这个注解应该是没有什么问题!

4.2 第二步

=====================================================================

使用切面注解进行标记,因为是对请求相关的日志打印,所以我们随便写一个控制层接口方法进行测试:

/**

  • @description: TODO

  • @author: HUALEI

  • @date: 2021-11-24

  • @time: 13:43

*/

@RestController

@RequestMapping(value = “/test”)

public class TestController {

private final static Logger log = LoggerFactory.getLogger(TestController.class);

@GetMapping(“/hello/{say}”)

@MyAnnotation(description = “测试接口”)

public String sayHello(@PathVariable(“say”) String content) {

log.info(“Client is saying:{}”, content);

return content;

}

}

4.3 第三步

=====================================================================

最后一步也是最关键的一步,在运行时解析注解执行切面操作,所以对应地写一个切面类:

image.gif

新建切面类后,考虑到日志的打印,这段代码必不可少:

/**

  • @description: TODO

  • @author: HUALEI

  • @date: 2021-11-19

  • @time: 15:56

*/

@Aspect

@Component

public class MyAnnotationAspect {

private static final Logger logger = LoggerFactory.getLogger(MyAnnotationAspect.class);

}

@Aspect 和 @Component 注解必不可少,@Component 大伙应该在熟悉不过了,将该类注入到 Spring 容器中;而另一个 @Aspect 注解的作用是把当前类标识成一个切面供容器去读取。

注意: 打印日志推荐使用的包是 slf4j.Logger 。

/**

  • 配置织入点

  • 切到所有被 @MyAnnotation 注解修饰的方法

*/

@Pointcut(“@annotation(com.xxx.xxx.annotation.MyAnnotation)”)

// @annotation(annotationType) 匹配指定注解为切入点的方法,annotationType 为注解的全路径

public void myAnnotationPointCut() {

}

配置织入点,切到所有被 @MyAnnotation 注解修饰的方法,不需要再方法体内编写实际的代码!

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

架构学习资料

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

新**

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-WiM5YKgk-1712891035920)]

架构学习资料

[外链图片转存中…(img-pcC5Wgpd-1712891035920)]

[外链图片转存中…(img-Oq9NjLBV-1712891035921)]

[外链图片转存中…(img-JXZ2YvjL-1712891035921)]

[外链图片转存中…(img-BJyUUM5O-1712891035921)]

[外链图片转存中…(img-yRcdnBCZ-1712891035922)]

由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-wOXrqAKz-1712891035922)]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值