初试AspectJ切面编程(AOP)

AspectJ框架是什么

AspectJ框架是一个用于面向切面编程(AOP)的框架。

它是基于Java语言的扩展,提供了更强大和灵活的AOP功能。AspectJ可以在编译时或者运行时织入代码,以实现横切关注点的功能。它支持更细粒度的切入点表达式,可以在类级别、方法级别甚至字段级别进行切面编程。AspectJ还提供了更多的通知类型,如前置通知、后置通知、异常通知、环绕通知等,使开发人员能够更精确地控制横切逻辑的执行时机。AspectJ可以独立于其他框架使用,但也可以与Spring等框架集成,提供更强大的AOP能力。

和SpringAop有什么区别

AspectJ框架和Spring AOP是两种不同的AOP实现方式。

AspectJ是一个独立的AOP框架,它提供了更强大和灵活的AOP功能。它使用编译时织入(CTW)或者运行时织入(RTW)的方式来实现横切关注点的织入。AspectJ支持更多的切入点表达式,可以在更细粒度的层面上进行切面编程。它还提供了更多的通知类型,如前置通知、后置通知、异常通知、环绕通知等。AspectJ可以独立于Spring框架使用,但也可以与Spring集成。

Spring AOP是Spring框架的一部分,它提供了一种更简化的AOP实现方式。它使用运行时代理(Proxy)的方式来实现横切关注点的织入。Spring AOP的功能相对较为有限,只支持方法级别的切入点表达式,通知类型也相对较少,包括前置通知、后置通知、异常通知。Spring AOP主要用于在Spring应用程序中实现横切关注点的功能。

总的来说,AspectJ提供了更强大和灵活的AOP功能,适用于更复杂的切面编程需求;而Spring AOP则提供了一种更简单和轻量级的AOP实现,适用于简单的切面编程需求,并且与Spring框架集成更紧密。

以实现自定义注解为例,两步学会使用

举例实现一个短时间内【限制接口请求次数】的注解

1.自定义注解

java 复制代码
package com.pth.server.core.http;

import java.lang.annotation.*;

/**
 * @author Administrator
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestRate {

    /**
     * 用户id
     * @return
     */
    String userId();

    /**
     * 限制次数
     * @return
     */
    int rateCount() default 3;

    /**
     * 过期时间
     * @return
     */
    int expireTime() default 10;

}

2.AOP处理实现

java 复制代码
package com.pth.server.core.http;

import cn.hutool.core.convert.Convert;
import com.pth.server.core.constants.RedisConstants;
import com.pth.server.core.exception.ServerException;
import com.pth.server.core.utils.ParamsUtil;
import net.sf.json.JSONObject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

@Component
@Aspect
public class RequestRateAspect {

    @Autowired
    protected RedisTemplate<String, String> redisTemplate;

    @Pointcut("@annotation(com.pth.server.core.http.RequestRate)")
    public void rateAspect(){}

    @Before("rateAspect()")
    public void beforeRate(JoinPoint joinPoint){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        // 获取注解中的参数 用于根据属性名获取属性值 因为某些注解的属性值是字符串 但实则是变量
        JSONObject paramsJson = ParamsUtil.getParams(joinPoint);
        RequestRate requestRate = method.getAnnotation(RequestRate.class);
        String userId = paramsJson.get(requestRate.userId()).toString();
        String key = RedisConstants.REQUEST_RATE + userId;
        Integer val = Convert.toInt(this.redisTemplate.opsForValue().get(key));
        if(val == null){
            val = 0;
        }else if(val >= requestRate.rateCount()){
            throw new ServerException("请求频率过高,请稍后再试");
        }
        this.redisTemplate.opsForValue().set(key, Convert.toStr(++val), requestRate.expireTime(), TimeUnit.MINUTES);
    }

    @After("rateAspect()")
    public void afterRate(JoinPoint joinPoint){



    }

}

使用注解

java 复制代码
@RequestMapping(path = "/test", method = RequestMethod.GET)
@RequestRate(userId = "userId")
void getImgCode(String userId, HttpServletResponse response) throws IOException {

}

注解说明(面向小白)

以上用到的注解是用于定义切面的。在面向切面编程(AOP)中,切面是一种用于横切关注点的模块化方式。

@Aspect 注解用于标识一个类为切面类,它通常与其他注解一起使用。

@Before 注解用于指定在目标方法执行之前执行的通知(advice)。

@After 注解用于指定在目标方法执行之后执行的通知。

@Pointcut 注解用于定义一个切入点,切入点是一个表达式,它定义了哪些方法将被切入。切入点表达式可以使用通配符和逻辑操作符来匹配目标方法。

这些注解一起提供了一种方式,通过在特定的切入点上执行额外的逻辑,从而实现横切关注点的功能,例如日志记录、性能监控等。

结尾

怎么样,是不是很简单,就那几个注解就实现了,我写的文章都很简洁,简单便捷,高效实用,哈哈~

相关推荐
Amarantine、沐风倩✨6 分钟前
设计一个监控摄像头物联网IOT(webRTC、音视频、文件存储)
java·物联网·音视频·webrtc·html5·视频编解码·七牛云存储
路在脚下@1 小时前
spring boot的配置文件属性注入到类的静态属性
java·spring boot·sql
啦啦右一1 小时前
Spring Boot | (一)Spring开发环境构建
spring boot·后端·spring
森屿Serien1 小时前
Spring Boot常用注解
java·spring boot·后端
苹果醋32 小时前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
Hello.Reader3 小时前
深入解析 Apache APISIX
java·apache
盛派网络小助手3 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
菠萝蚊鸭3 小时前
Dhatim FastExcel 读写 Excel 文件
java·excel·fastexcel
旭东怪3 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
007php0073 小时前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程