什么是注解;注解的原理是什么?若依中的注解说明

干货版本

自定一个每次调用方法都输出 好好学习天天向上的 注解

在Java中,你可以通过自定义注解和使用AOP(面向切面编程)来实现这个需求。以下是一个简单的示例:
首先,定义一个自定义注解:

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 StudyReminder {
}

然后,使用Spring AOP或其他支持AOP的框架,创建一个切面类来处理这个注解:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class StudyReminderAspect {

    @Around("@annotation(StudyReminder)")
    public Object logStudyMessage(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("好好学习天天向上");
        return joinPoint.proceed(); // 执行原方法
    }
}

现在,你可以在任何方法上使用@StudyReminder注解,每次调用该方法时,都会先输出“好好学习天天向上”的提示:

罗里吧嗦版本

SpringBoot支持我们开发者能够自定义注解,从而实现一些项目中遇到的特定问题,这个功能不知道用过的小伙伴们多不多,反正我是用得不多,但是使用之后就会发现,实在是太便捷了,配合上AOP,简直是开发的大救星,这边就简单的介绍利用SpringBoot自定义注解来实现日志的收集和问题的监控功能。

在项目的开发中,日志的打印与收集整理一向是一件十分重要的事,可以毫不夸张的说,如果日志信息详细合理,对于我们后期定位bug,修复功能起着事倍功半的作用,但是打印日志也是一件繁琐的事情,一是有很多日志是属于重复日志,基本每个方法都要打印,写起来就是冗余代码;二来本来流畅的代码,前边加一条日志打印,后边加一条日志打印,读起来感受不是很好;三来打印日志本来就不影响代码功能的实现,有些小伙伴因为时间急给漏了,忘了也是很常有的事,所以如果能够让每个方法自动生成关键的日志信息,然后存储到数据中,那么不仅能够节省开发时间,提高开发效率,也能让我们的代码显得更加简洁明了。

利用SpringBoot中的自定义注解加上AOP就可以轻松的帮助我们实现上面说的功能,话不多说,直接上干货——代码:

定义

一、首先需要定义一个注解的interface,也就是我们自定义注解的注解名,同时也要定义里面的内部参数

1.jpg

在SpringBoot中,有四个元注解[详见附录A],它们被称为注解的注解,我们在自定义注解的时候,就会用到它们,下面对他们分别做个简单的介绍:
@Target:这个注解就是规定了我们自定义的注解所使用的的范围,里面有个属性叫ElementType,关于这个属性有着很多值:
@Retention:这个注解规定了我们自定义注解的生命周期,里面有个属性叫RetentionPolicy,关于这个属性有三个值:
@Inherited:这个注解是一个标记注解,表明被标注的类型是可以被继承的。
@Documented:该注解表明被注解信息是否被添加在Javadoc中。

实体类

二、定义完自定义的注解接口后,接下来就是要定义相对应的实体类了,我们这里实现的功能是对每个方法的执行结果进行日志的记录,既然是记录,那肯定是要落库的,这样才能方便日后的查看,否则这些记录就没有太大的意义,因此要定义一个日志的实体类,作为持久化对象。

2.jpg

切面逻辑

三、定义完实体对象后,接下来就是要写切面逻辑,在逻辑里实现对方法输出结果的捕获与处理,持久化。我们知道一个方法的输出结果无非是两种,一个是方法执行成功,输出正确的结果;一个是方法执行失败,中途报错。对于这两种不同的执行结果,分别都需要用不同的逻辑来进行处理。

1.方法执行成功,输出正确的结果:

@AfterReturning(value="xxx()", returning = "returnValue")
public void writeCrmLog(JoinPoint joinPoint, Object returnValue) throws Exception{
    /**获取相对应的方法参数,存入数据库中*/
    ........
}

2.方法执行失败,中途报错:

@AfterReturning(value="xxx()", throwing= "ex")
public void throwingExCrmLog(JoinPoint joinPoint, Object returnValue) throws Exception{
    /**获取相对应的方法参数,存入数据库中*/
    ........
}

测试

四、利用切面实现的方法操作日志的记录,既简化了代码,提高了开发效率,又减少了日记的遗漏,规范了日记格式,对于后续定位问题提供了更方便快捷的方式,可谓是一举多得,是开发代码中不可或缺的重要组成部分。

@GetMapping

@GetMapping是@RequestMapping(method = RequestMethod.GET)缩写的组合注解,用于将 HTTP 的get 请求映射到特定处理程序的方法注解。
@GetMapping就是@RequestMapping附加了get请求方法。也就是说@GetMapping就是一个只能用来处理http的get请求的注解,比较专一,只能干这一件事,不像@RequestMapping可以处理多种http的请求。
在一般情况下我们开发可能都是用@RequestMapping(method=RequestMethod.×××),因为@RequestMapping可以直接替代以上两个注解,但是以上两个注解并不能替代@RequestMapping。
类似的组合注解还有上面提到的:@PutMapping、@DeleteMapping、@PatchMapping三个注解

@PostMapping

@DeleteMapping

@Validated

@RequiredArgsConstructor

生成带有必需参数的构造函数。 必需的参数是最终字段和具有约束的字段,例如@NonNull 。
完整的文档可在@lconstructor的项目lombok功能页面上找到 。即使未列出,该注释也具有onConstructor参数。 有关更多详细信息,请参见完整的文档。
这个是基于lombok的使用时必须导入lombok包。

@RestController

@RepeatSubmit

参考文档:https://blog.csdn.net/Michelle_Zhong/article/details/125004718

@Repeatsubmit注解是Spring框架提供的用于防止表单重复提交的注解

附录A

@Target:这个注解就是规定了我们自定义的注解所使用的的范围,里面有个属性叫ElementType,关于这个属性有着很多值:

  ElementType.TYPE    类,接口(包括注解类型),enum声明
  ElementType.FIELD    字段声明(包括枚举常量)
  ElementType.METHOD    方法
  ElementType.PARAMETER    参数
  ElementType.CONSTRUCTOR    构造器
  ElementType.LOCAL_VARIABLE    局部变量
  ElementType.ANNOTATION_TYPE    注解类型
  ElementType.PACKAGE    包
  ElementType.TYPE_PARAMETER    类型参数
  ElementType.TYPE_USE    类型的注解,如泛型

@Retention:这个注解规定了我们自定义注解的生命周期,里面有个属性叫RetentionPolicy,关于这个属性有三个值:

  RetentionPolicy.SOURCE    编译后即丢弃,自定义注解在编译结束后就不再产生意义,因此不会写入到Class文件中
  RetentionPolicy.CLASS    类加载时丢弃,编译后保留(在Class文件中存在,但是JVM运行时将会忽略),默认使用这种方式
  RetentionPolicy.RUNTIME    运行期保留,在Class文件中存在,JVM运行时保留,可以通过反射机制读取该注解的信息

@Inherited:这个注解是一个标记注解,表明被标注的类型是可以被继承的。

@Documented:该注解表明被注解信息是否被添加在Javadoc中。

标签: 注解

相关阅读

  • 测试信息
  • 开发商:阿里巴巴
  • 版本号:1.0
  • 配色:(企业家)” 推选活动结果
  • 测试信息
  • 测试信息
  • 测试信息