java 自定义注解 加 aop实现优雅编程

自定义注解

简单的Java自定义注解的示例:

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyCustomAnnotation {
    String value() default ""; // 定义一个名为"value"的成员,默认值为空字符串
    int priority() default 0;  // 定义一个名为"priority"的成员,默认值为0
}

在这个示例中,定义了一个名为MyCustomAnnotation的自定义注解,它有两个成员:value和priority。@Retention注解指定了注解在运行时可见,@Target注解指定了注解可以应用在方法上。
@Retention,元注解(元注解(Meta-Annotation)是用于注解其他注解的特殊注解。换句话说,元注解是一种用于定义和配置自定义注解的注解),用于指,定自定义注解的保留策略,即注解在什么级别可见。它有三个预定义的保留策略:

  • RetentionPolicy.SOURCE: 注解仅存在于源代码中,在编译后不会包含在编译好的类文件中。这意味着注解仅在开发阶段使用,对运行时没有任何影响。
  • RetentionPolicy.CLASS: 注解存在于源代码和编译后的类文件中,但在运行时不可见。这是默认的保留策略,如果你在定义注解时没有显式地指定保留策略,它将被默认为CLASS。
  • RetentionPolicy.RUNTIME: 注解存在于源代码、编译后的类文件和运行时环境中。这允许你在运行时通过反射等机制访问和解析注解信息。
    通常,如果希望在运行时使用自定义注解,应该将@Retention设置为RetentionPolicy.RUNTIME。这允许通过反射在运行时访问注解信息并执行相应的操作。
    @Target,用于指定自定义注解可以应用的目标元素类型。换句话说,它规定了你可以在哪些程序元素上使用自定义注解。
    常见的@Target枚举常量:
  • ElementType.TYPE: 可以应用于类、接口、枚举等类型声明。
  • ElementType.FIELD: 可以应用于字段(成员变量)。
  • ElementType.METHOD: 可以应用于方法。
  • ElementType.PARAMETER: 可以应用于方法参数。
  • ElementType.CONSTRUCTOR: 可以应用于构造方法。
  • ElementType.LOCAL_VARIABLE: 可以应用于局部变量。
  • ElementType.ANNOTATION_TYPE: 可以应用于注解类型声明。
  • ElementType.PACKAGE: 可以应用于包声明。

使用注解

在代码中使用这个自定义注解,例如:

public class MyClass {
    @MyCustomAnnotation(value = "This is a custom annotation", priority = 2)
    public void myMethod() {
        // 方法内容
    }
}

自定义注解本身并不会提供任何额外的功能,它们只是为了给代码添加元数据。如果你希望在程序中根据注解来执行某些操作,需要使用反射或其他技术来解析注解并采取相应的行动。

AOP 加 注解 实现非侵入式编程

结合AOP(面向切面编程)和自定义注解可以实现在特定方法执行前、执行后、异常抛出等切面点添加额外的逻辑。AOP可以在不修改原有业务逻辑的情况下,通过将横切关注点(如日志、安全性、事务等)从业务逻辑中分离出来,提供更好的可维护性和扩展性。

以下是一个使用自定义注解结合AOP的简单示例,展示如何在方法执行前后记录日志:

定义自定义注解:

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Loggable {
}

创建一个切面类来实现日志逻辑:

import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.*;

@Aspect
@Component
public class LoggingAspect {

    @Before("@annotation(Loggable)") // 在带有 @Loggable 注解的方法执行前执行
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("Before executing: " + joinPoint.getSignature().getName());
    }

    @AfterReturning("@annotation(Loggable)") // 在带有 @Loggable 注解的方法正常返回后执行
    public void logAfterReturning(JoinPoint joinPoint) {
        System.out.println("After returning from: " + joinPoint.getSignature().getName());
    }

    @AfterThrowing(value = "@annotation(Loggable)", throwing = "ex") // 在带有 @Loggable 注解的方法抛出异常时执行
    public void logAfterThrowing(JoinPoint joinPoint, Exception ex) {
        System.out.println("After throwing exception in: " + joinPoint.getSignature().getName());
        System.out.println("Exception: " + ex.getMessage());
    }
}

在业务代码中使用自定义注解:

@Service
public class MyService {

    @Loggable
    public void doSomething() {
        System.out.println("Doing something...");
    }

    public void doAnotherThing() {
        System.out.println("Doing another thing...");
    }
}

在上述示例中,使用@Loggable注解标记的方法会触发AOP切面中定义的日志逻辑。而未标记的方法不会受到影响。

要使AOP生效,需要确保已经配置了适当的AOP支持,如Spring AOP或AspectJ,具体配置会根据所使用的框架而有所不同。这个示例展示了如何通过自定义注解和AOP结合,将横切关注点(日志记录)从业务逻辑中分离出来

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

羱滒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值