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
注解用于定义一个切入点,切入点是一个表达式,它定义了哪些方法将被切入。切入点表达式可以使用通配符和逻辑操作符来匹配目标方法。这些注解一起提供了一种方式,通过在特定的切入点上执行额外的逻辑,从而实现横切关注点的功能,例如日志记录、性能监控等。
结尾
怎么样,是不是很简单,就那几个注解就实现了,我写的文章都很简洁,简单便捷,高效实用,哈哈~