SpringBoot中自定义注解

本文详细讲解了如何在Java中自定义注解,包括注解的定义、元注解的使用(如@Target和@Retention)以及实际应用场景。通过实例演示了如何在类、方法和参数上应用自定义注解,以及如何通过反射获取并处理这些注解信息。

注解是一种能被添加到java代码中的元数据(python中的函数装饰器),类、方法、参数、变量和包都可以用注解来修饰。用来定义一个类、属性或者一些方法,以便程序能被捕译处理。相当于一个说明文件,告诉应用程序某个被注解的类或者属性是什么,要怎么处理。对被修饰的代码本身没有直接影响。
使用范围:
1)为编译器提供信息:注解能被编译器检测到错误或抑制警告。
2)编译时和部署时的处理: 软件工具能处理注解信息从而生成代码,XML文件等等。
3)运行时的处理:有些注解在运行时能被检测到。
自定义注解的步骤:
第一步:定义注解
第二步:配置注解
第三步:解析注解

1.最基本的注解定义

public @interface MyAnnotation{
	public String name();
	int age();
	String sex() default "女"}

在自定义注解中,其实现部分只能定义注解类型元素!
2.常用的元注解
元注解:专门修饰注解的注解
@Target
@Target是专门用来限定某个自定义注解(如上面的@interface MyAnnotation)能够被应用在哪些Java元素上面的。枚举类型。
因此,我们可以在使用@Target时指定注解的使用范围

//@MyAnnotation被限定只能使用在(类、接口)TYPE或(方法)METHOD上面
@Target(value = {ElementType.METHOD,ElementType.TYPE})
public @interface MyAnnotation {
    public String name();
    int age();
    String sex() default "女";
}

@Retention注解,用来修饰自定义注解的生命力。
a.如果一个注解被定义为RetentionPolicy.SOURCE,则它将被限定在Java源文件中,那么这个注解即不会参与编译也不会在运行期起任何作用,这个注解就和一个注释是一样的效果,只能被阅读Java文件的人看到;
  b.如果一个注解被定义为RetentionPolicy.CLASS,则它将被编译到Class文件中,那么编译器可以在编译时根据注解做一些处理动作,但是运行时JVM(Java虚拟机)会忽略它,我们在运行期也不能读取到,是默认的;
  c.如果一个注解被定义为RetentionPolicy.RUNTIME,那么这个注解可以在运行期的加载阶段被加载到Class对象中。那么在程序运行阶段,我们可以通过反射得到这个注解,并通过判断是否有这个注解或这个注解中属性的值,从而执行不同的程序代码段。我们实际开发中的自定义注解几乎都是使用的RetentionPolicy.RUNTIME。

使用此注解修饰自定义注解生命力的示例如下:

//设置注解的生命力在运行期
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    public String name();
    int age();
    String sex() default "女";
}

@Inherited注解,是指定某个自定义注解如果写在了父类的声明部分,那么子类(继承关系)的声明部分也能自动拥有该注解。该注解只对@Target被定义为ElementType.TYPE的自定义注解起作用。

自定义注解举例

第一步:自定义的注解如下

package com.example.demo.config;

import java.lang.annotation.*;

@Target(value={ElementType.METHOD}) //只能被使用在方法上面
@Retention(RetentionPolicy.RUNTIME)//设置注解的生命力在运行期,那么这个注解可以在运行期的加载阶段被加载到Class对象中。那么在程序运行阶段,我们可以通过反射得到这个注解,并通过判断是否有这个注解或这个注解中属性的值,从而执行不同的程序代码段
@Documented
public @interface MyAnnotation {
    public String name();
    int age();
    String sex() default "女";
    String[] hobby();
}

第二步:创建一个类,新建方法使用该注解

package com.example.demo.controller;
import com.example.demo.config.MyAnnotation

public class UserController{
	@MyAnnotation(name = "张三",age = 18, hobby ={"跑步","打游戏"})//注解里面的字段
	public String get(){
		return "Hello Annotation";
	}
}

第三步:利用反射获取注解。创建一个类,代码如下:

package com.example.demo.test;

import com.example.demo.config.MyAnnotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) {
        try {
            //获取Class对象
            Class mylass = Class.forName("com.example.demo.controller.UserController");
            //获得该对象身上配置的所有的注解
            Annotation[] annotations = mylass.getAnnotations();
            System.out.println(annotations.toString());
            //获取里面的一个方法
            Method method = mylass.getMethod("get");
            //判断该元素上是否配置有某个指定的注解
            if(method.isAnnotationPresent(MyAnnotation.class)){
                System.out.println("UserController类的get方法上配置了MyAnnotation注解!");
                //获取该元素上指定类型的注解
                MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
                System.out.println("name: " + myAnnotation.name() + ", age: " + myAnnotation.age()
                        + ",sex:"+myAnnotation.sex()+", hobby: " + myAnnotation.hobby()[0]);
            }else{
                System.out.println("UserController类的get方法上没有配置MyAnnotation注解!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

打印结果
在这里插入图片描述

### 创建和使用自定义注解 #### 定义自定义注解 为了在 Spring Boot 应用程序中创建自定义注解,首先需要定义该注解。这可以通过 `@interface` 关键字来完成。例如: ```java 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 LogAsync { String value() default ""; } ``` 这段代码展示了如何定义名为 `LogAsync` 的自定义注解[^3]。 #### 注册 AOP 依赖 为了让应用程序支持面向切面编程(AOP),以便能够拦截带有特定注解的方法调用,在项目的 `pom.xml` 文件中加入 AOP 启动器依赖项是必要的操作之一: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> ``` 此片段说明了引入 AOP 支持所需的 Maven 依赖配置[^1]。 #### 实现切面逻辑 接下来要做的就是编写一个切面类,用于处理被标记有之前所定义的自定义注解方法的行为。下面是一个简单的例子展示怎样做这一点: ```java 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 LoggingAspect { @Around("@annotation(LogAsync)") public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.currentTimeMillis(); try { return joinPoint.proceed(); } finally { long executionTime = System.currentTimeMillis() - start; System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms"); } } } ``` 这里实现了围绕通知(`@Around`),它会在任何标注了 `LogAsync` 注解的方法执行前后运行,并打印出其耗时情况。 #### 使用自定义注解 一旦完成了以上步骤,则可以在业务逻辑层中的服务或者控制器组件里自由运用新建立起来的注解。比如在一个 RESTful API 控制器里面像这样去装饰某个端点函数: ```java @RestController @RequestMapping("/api") public class MyController { @GetMapping("/example") @LogAsync("This is an async logging example.") public ResponseEntity<String> getExample() { // Some business logic here... return new ResponseEntity<>("Success", HttpStatus.OK); } } ``` 上述代码段显示了一个典型的 REST Controller 方法,其中包含了前面提到过的 `@LogAsync` 自定义注解的应用实例。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值