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

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

结尾

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

相关推荐
morris1314 分钟前
【SpringBoot】Xss的常见攻击方式与防御手段
java·spring boot·xss·csp
monkey_meng21 分钟前
【Rust中的迭代器】
开发语言·后端·rust
余衫马24 分钟前
Rust-Trait 特征编程
开发语言·后端·rust
monkey_meng28 分钟前
【Rust中多线程同步机制】
开发语言·redis·后端·rust
七星静香29 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
Jacob程序员30 分钟前
java导出word文件(手绘)
java·开发语言·word
ZHOUPUYU30 分钟前
IntelliJ IDEA超详细下载安装教程(附安装包)
java·ide·intellij-idea
stewie634 分钟前
在IDEA中使用Git
java·git
Elaine2023911 小时前
06 网络编程基础
java·网络
G丶AEOM1 小时前
分布式——BASE理论
java·分布式·八股