Java自定义注解与AOP的完美融合

一、引言

在现代Java开发中,面向切面编程(Aspect-Oriented Programming,AOP)已经成为一种重要的编程范式。它允许我们将横切关注点(如日志记录、事务管理、权限校验等)从业务逻辑中分离出来,从而提高代码的可维护性和可扩展性。而自定义注解则是实现AOP功能的一种强大工具。通过自定义注解,我们可以清晰地标识出需要进行切面处理的方法或类,让AOP框架能够根据注解来动态地织入增强逻辑。本文将深入探讨Java自定义注解与AOP的结合,从自定义注解的创建到在AOP中的应用,帮助读者更好地理解和使用这一技术。

二、AOP

AOP概述

AOP:Aspect Oriented Programming(面向切面编程、面向方面编程),其实就是面向特定方法编程。

我们想象一个场景,我们写的系统中的某个部分功能运行较慢,需要定位执行耗时较长的业务方法,此时需要统计每一个业务方法的执行耗时。

如果我们对每一个业务方法手动的插入检查,这将会是巨大的工程量,且改动原始方法的过程中也会不小心疏忽。

所以,我们提出 AOP 概念,面对不同的方法,我们重复使用一个功能的时候,我们设计出一个模板套用即可。

AOP依赖

<!--        aop -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

AOP 核心概念

连接点 : ProceedingJoinPoint  JoinPoint,可以被AOP控制的方法(暗含方法执行时的相关信息)

注解通知 : Advice,指哪些重复的逻辑,也就是共性功能(最终体现为一个方法)

注解切入点 : Pointcut,匹配连接点的条件,通知仅会在切入点方法执行时被应用

类注解切面:Aspect,描述这个类的通知与切入点的对应关系(通知+切入点)

(注解切入点的参数)目标对象:Target,通知所应用的对象

视图参考如下:

AOP进阶

通知类型

  1. @Around:环绕通知,此注解标注的通知方法在目标方法前、后都被执行
  2. @Before :前置通知,此注解标注的通知方法在目标方法前被执行
  3. @After :后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行
  4. @AfterReturning :返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执行
  5. @AfterThrowing:异常后通知,此注解标注的通知方法发生异常后执行

通知顺序

1、不同切面类中,默认按照切面类的类名字母排序

  • 目标方法前的通知方法:字母排名靠前的先执行
  • 目标方法后的通知方法:字母排名靠前的后执行

2、用 @Order(数字) 加在切面类上来控制顺序

  • 目标方法前的通知方法:数字小的先执行
  • 目标方法后的通知方法:数字小的后执行

常见的切入点表达式

1. execution(不太推荐)

execution 是最常用的切入点表达式,用于匹配方法的执行。

2. @annotation 注解

@annotation 用于匹配那些被指定注解修饰的方法。它关注的是方法上的注解,而不是类或参数上的注解。

3. @within 注解

@within 用于匹配那些定义在带有指定注解的类中的所有方法,而不仅仅是被注解修饰的方法。

三、Java自定义注解基础

(一)什么是注解

        注解是Java语言中的一种元数据形式,它提供了关于程序代码的额外信息,但并不直接影响代码的运行。注解可以应用于类、方法、字段等程序元素上。Java内置了一些注解,如@Override@Deprecated等,但Java也允许我们自定义注解。

(二)元注解

在Java中,注解本身也可以被注解修饰,这些用于修饰注解的注解被称为元注解(Meta-Annotation)。元注解主要用于定义注解的属性和行为,为注解提供更丰富的语义和功能。Java提供了几种标准的元注解,这些元注解在自定义注解时非常关键。

(1)@Retention

@Retention元注解用于指定注解的保留策略,即注解在程序的生命周期中可以被保留到什么阶段。它接受一个RetentionPolicy枚举值,定义了注解的保留范围:

  • RetentionPolicy.SOURCE:注解仅在源代码阶段保留,编译时会被丢弃,不会进入字节码文件。这种保留策略通常用于编译时的检查或代码生成工具。

  • RetentionPolicy.CLASS:注解在编译阶段保留,会被写入字节码文件,但在运行时无法通过反射访问。这种策略适用于一些需要在字节码层面进行处理的场景。

  • RetentionPolicy.RUNTIME:注解在运行时保留,可以通过反射获取注解的信息。这是AOP和框架(如Spring)中常用的保留策略,因为它们需要在运行时动态地处理注解。

(2)@Target

@Target元注解用于指定注解可以应用的目标类型。它接受一个ElementType枚举值,定义了注解可以修饰的程序元素类型:

  • ElementType.TYPE:注解可以应用于类、接口(包括注解类型)或枚举声明。

  • ElementType.FIELD:注解可以应用于字段(包括枚举常量)。

  • ElementType.METHOD:注解可以应用于方法。

  • ElementType.PARAMETER:注解可以应用于方法或构造器的参数。

  • ElementType.CONSTRUCTOR:注解可以应用于构造器。

  • ElementType.LOCAL_VARIABLE:注解可以应用于局部变量。

  • ElementType.ANNOTATION_TYPE:注解可以应用于注解类型。

  • ElementType.PACKAGE:注解可以应用于包声明。

(3)@Documented

@Documented元注解用于指定注解是否会被包含在JavaDoc文档中。当一个注解被@Documented修饰时,它会在生成的JavaDoc文档中显示。这对于开发框架或库时非常有用,因为它可以帮助开发者更好地理解注解的用途。

(4)@Inherited

@Inherited元注解用于指定注解是否可以被子类继承。当一个类被某个注解修饰,且该注解被@Inherited修饰时,其子类也会继承该注解。需要注意的是,@Inherited仅对类的继承有效,对方法或字段的继承无效。

(5)@Repeatable

@Repeatable元注解是Java 8引入的,用于支持注解的重复使用。在默认情况下,一个注解在一个程序元素上只能使用一次。通过@Repeatable,可以在同一个程序元素上多次使用同一个注解。

        元注解在Java注解体系中起着关键作用,它们定义了注解的生命周期、适用范围、是否可继承、是否可重复等重要属性。通过合理使用元注解,可以为自定义注解赋予更丰富的语义和行为,使其能够更好地满足开发需求。

在实际开发中,元注解是自定义注解的基础,它们帮助开发者明确注解的使用方式和范围,从而提高代码的可读性和可维护性。同时,我们懂得如何使用常用的注解即可。

(三)自定义注解登录拦截

根据我上一篇文章 Java拦截器应用_java异常拦截器-CSDN博客 拦截器知识。

我们拦截器有时候调节拦截比较吃力,总是需要微调所拦截的控制类

这次我们学会自定义注解后,可以通过注解方式通知系统我们拦截哪个控制器类,不拦截哪个控制器类

定义登录校验拦截的自定义注解

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

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface LoginCheck {
    String value() default "";
}

定义无需登录校验拦截的自定义注解

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

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface SkipLoginCheck {
    String value() default "";
}

定义切面类

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect
@Component
public class LoginCheckAspect{

    // 定义方法切点
    @Pointcut("@annotation(com.angindem.aop.interfaces.LoginCheck)")
    private void at() {
    }

    // 定义类方法切点
    @Pointcut("@within(com.angindem.aop.interfaces.LoginCheck)")
    private void wt() {
    }

    // 匹配标注有 @Skip 注解的类或方法
    @Pointcut("@within(com.angindem.aop.interfaces.SkipLoginCheck) || @annotation(com.angindem.aop.interfaces.SkipLoginCheck)")
    public void st() {
    }

    // 逻辑拦截,当遇到 Skip 注解忽略拦截
    @Before("(at() || wt()) && !st()")
    public void befor() {
        // 登录拦截逻辑
    }

    @Around("(at() || wt()) && !st()")
    public Object after(ProceedingJoinPoint joinPoint) throws Throwable {
//        调用原来方法执行
        return joinPoint.proceed();
    }
}

通过以上逻辑,可以直接使用 两个 自定义注解灵活拦截。

### 部署 Stable Diffusion 的准备工作 为了成功部署 Stable Diffusion,在本地环境中需完成几个关键准备事项。确保安装了 Python 和 Git 工具,因为这些对于获取源码和管理依赖项至关重要。 #### 安装必要的软件包和支持库 建议创建一个新的虚拟环境来隔离项目的依赖关系。这可以通过 Anaconda 或者 venv 实现: ```bash conda create -n sd python=3.9 conda activate sd ``` 或者使用 `venv`: ```bash python -m venv sd-env source sd-env/bin/activate # Unix or macOS sd-env\Scripts\activate # Windows ``` ### 下载预训练模型 Stable Diffusion 要求有预先训练好的模型权重文件以便能够正常工作。可以从官方资源或者其他可信赖的地方获得这些权重文件[^2]。 ### 获取并配置项目代码 接着要做的就是把最新的 Stable Diffusion WebUI 版本拉取下来。在命令行工具里执行如下指令可以实现这一点;这里假设目标路径为桌面下的特定位置[^3]: ```bash git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git ~/Desktop/stable-diffusion-webui cd ~/Desktop/stable-diffusion-webui ``` ### 设置 GPU 支持 (如果适用) 当打算利用 NVIDIA 显卡加速推理速度时,则需要确认 PyTorch 及 CUDA 是否已经正确设置好。下面这段简单的测试脚本可以帮助验证这一情况[^4]: ```python import torch print(f"Torch version: {torch.__version__}") if torch.cuda.is_available(): print("CUDA is available!") else: print("No CUDA detected.") ``` 一旦上述步骤都顺利完成之后,就可以按照具体文档中的指导进一步操作,比如调整参数、启动服务端口等等。整个过程中遇到任何疑问都可以查阅相关资料或社区支持寻求帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值