苍穹外卖Day3碰到的元注解

1. @Target

@Target注解用于指定自定义注解可以应用的Java元素范围。它的参数是ElementType的枚举值,可以指定一个或多个范围。使用@Target可以限制注解只能用于特定的程序元素,如类、方法、字段等。

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target(ElementType.METHOD) // 只能用于方法
public @interface CustomAnnotation {
    // 注解的成员
}

ElementType的常用值包括:

  • TYPE: 类、接口(包括注解类型)或枚举声明
  • FIELD: 字段声明(包括枚举常量)
  • METHOD: 方法声明
  • PARAMETER: 参数声明
  • CONSTRUCTOR: 构造方法声明
  • LOCAL_VARIABLE: 局部变量声明
  • ANNOTATION_TYPE: 注解类型声明
  • PACKAGE: 包声明

2.@Retention

@Retention注解指定自定义注解的保留策略,即注解的信息保留到哪个阶段。它的参数是RetentionPolicy的枚举值,决定了注解在源代码(Source)、字节码(Class)或运行时(Runtime)被保留。

例如下面的代码定义了一个注解@CustomAnnotation,它在运行时依然可用:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME) // 在运行时保留
public @interface CustomAnnotation {
    // 注解的成员
}

RetentionPolicy的常用值包括:

  • SOURCE: 注解只在源代码中保留,编译器编译时会被忽略。
  • CLASS: 注解在编译到字节码文件中,但在运行时不会被虚拟机保留。这是默认的保留策略。
  • RUNTIME: 注解在运行时保留,可以通过反射获取到。

@Target@Retention一起使用,可以精确控制自定义注解的使用场景和生命周期,使得注解的设计更加灵活和强大。

比如说苍穹外卖Day3中自定义注解AutoFill时,为了这个注解能够加在方法(ElementType.METHOD)上,来标识某个方法需要进行功能字段自动填充处理,就是通过下面这段代码实现的:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
    //数据库操作类型:UPDATE INSERT
    OperationType value();
}

其中

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)

可以简单记忆成固定搭配

3. @Aspect

@Aspect是一个用于定义切面的注解。在面向切面编程(AOP)中,切面是一个可以包含多个通知(Advice)和切点(Pointcut)的模块。通知是在特定的程序执行点插入的代码片段,而切点定义了那些执行点。@Aspect注解告诉Spring框架,该类包含AOP切面的定义。

4.@Component

@Component是一个通用的立体注解,它用来标识一个Spring管理的组件。当Spring框架的扫描器检测到这个注解时,它会在Spring应用上下文中创建一个该类的实例。这是实现依赖注入的一种方式。@Component可以被视为告诉Spring,“这是一个组件,我希望你管理它”。

5.@slf4j

@slf4j是一个来自Lombok库的注解,用于自动注入一个SLF4J(Simple Logging Facade for Java)类型的日志对象。它在编译时会自动生成一个日志对象,这样你就可以在你的类中使用日志对象来记录日志,而不需要手动创建它。通常,这能让日志记录变得更加简洁。6.6.

import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;

@Aspect
@Component
@Slf4j
public class MyService {

    public void performAction() {
        log.info("Performing an action in MyService");
        // ... method implementation
    }
}

6. @PointCut 

切面类定义过程中需要两个注解,一个是@PointCut,一个是通知,我们先来说接入点。

@Pointcut注解用于定义一个切点(Pointcut),即一组满足特定条件的连接点(Join Point),其中连接点代表了程序执行的某个特定位置,例如方法的执行或异常的处理。切点表达式决定了在哪些连接点上应用通知(Advice)。这样,你可以重用切点表达式,并将其与不同的通知关联起来。

   @Aspect
   public class MyAspect {
       @Pointcut("execution(* com.example.service.*.*(..))")
       public void serviceMethods() {
           // 切点表达式
       }
   }

@Pointcut("execution(* com.example.service.*.*(..))")表示serviceMethods()方法标记有@Pointcut注解,其表达式表示应用于com.example.service包下所有类的所有方法。

苍穹外卖Day3里用到了

@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")

这个注解的含义是:

匹配com.sky.mapper包下所有类(*代表所有类)的所有方法(第二个*代表所有方法),但仅应用于那些被指定注解com.sky.annotation.AutoFill标记的方法。

7.@Before

@Before注解用于定义一个前置通知(Before Advice),它将在匹配的方法执行之前执行。你可以指定一个切点表达式或引用一个已经定义的切点来决定这个前置通知应用的位置。前置通知用于在方法实际执行之前执行某些操作,例如安全检查、初始化资源、日志记录等。

   @Aspect
   public class MyAspect {
       @Before("serviceMethods()")
       public void beforeServiceMethods(JoinPoint joinPoint) {
           // 前置通知的逻辑
           System.out.println("Before executing method: " + joinPoint.getSignature().getName());
       }
   }

在这个例子中,beforeServiceMethods()方法标记有@Before注解,并引用了serviceMethods()定义的切点。这意味着在com.example.service包中的任何方法执行之前,都会先执行beforeServiceMethods()中的代码。 

8. @annotation

 在@Pointcut注解中使用@annotation可以让你根据方法上的注解来过滤方法,你可以根据自定义的注解来选择哪些方法将触发通知的执行。

// 自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Audit {
    // 注解中可以定义属性,例如记录操作类型等
}

// 切面类
@Aspect
public class AuditAspect {

    // 切点表达式,匹配所有被@Audit注解标记的方法
    @Pointcut("@annotation(Audit)")
    public void auditMethods() {
    }

    // 通知方法,将在匹配的方法执行前执行
    @Before("auditMethods()")
    public void beforeAudit(JoinPoint joinPoint) {
        // 通知中的逻辑,例如记录日志
        System.out.println("Audit action before method: " + joinPoint.getSignature().getName());
    }
}

该切点只匹配那些被@Audit注解标记的方法。

相关推荐

  1. 苍穹Day3碰到注解

    2024-03-23 20:20:01       44 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-23 20:20:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-23 20:20:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-23 20:20:01       82 阅读
  4. Python语言-面向对象

    2024-03-23 20:20:01       91 阅读

热门阅读

  1. Eureka注册中心

    2024-03-23 20:20:01       40 阅读
  2. C语言经典面试题目(二十)

    2024-03-23 20:20:01       43 阅读
  3. python之exec与eval

    2024-03-23 20:20:01       46 阅读
  4. Acwing 104. 货仓选址

    2024-03-23 20:20:01       39 阅读
  5. MySQL 中的事务和存储引擎

    2024-03-23 20:20:01       36 阅读
  6. 基于单片机的机电控制实训平台设计

    2024-03-23 20:20:01       41 阅读
  7. git -- 提交规范

    2024-03-23 20:20:01       40 阅读
  8. ECS Fargate 上部署 SkyWalking UI 并通过 ALB 提供服务

    2024-03-23 20:20:01       35 阅读
  9. 如何从小白,到掌握Python

    2024-03-23 20:20:01       38 阅读
  10. 【MySQL】巧解客户连续递增交易

    2024-03-23 20:20:01       37 阅读
  11. HttpURLConnection的使用

    2024-03-23 20:20:01       33 阅读