初试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 注解用于定义一个切入点,切入点是一个表达式,它定义了哪些方法将被切入。切入点表达式可以使用通配符和逻辑操作符来匹配目标方法。

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

结尾

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

相关推荐
言慢行善4 分钟前
SpringBoot中的注解介绍
java·spring boot·后端
一勺菠萝丶6 分钟前
管理后台使用手册在线预览与首次登录引导弹窗实现
java·前端·数据库
小村儿8 分钟前
连载05-Claude Skill 不是抄模板:真正管用的 Skill,都是从实战里提炼出来的
前端·后端·ai编程
无巧不成书021819 分钟前
Java包(package)全解:从定义、使用到避坑,新手零基础入门到实战
java·开发语言·package·java包
身如柳絮随风扬30 分钟前
SpringMVC 异常处理?Spring 父子容器?
java·spring·mvc
光电大美美-见合八方中国芯31 分钟前
用于无色波分复用光网络的 10.7 Gb/s 反射式电吸收调制器与半导体光放大器单片集成
网络·后端·ai·云计算·wpf·信息与通信·模块测试
鬼先生_sir38 分钟前
Spring AI Alibaba 用户使用手册
java·人工智能·springai
有梦想的小何38 分钟前
从0到1搭建可靠消息链路:RocketMQ重试 + Redis幂等实战
java·redis·bootstrap·rocketmq
大数据新鸟42 分钟前
HashMap、Hashtable、ConcurrentHashMap 核心对比
java
MX_93591 小时前
Spring MVC拦截器
java·后端·spring·mvc