👳我亲爱的各位大佬们好😘😘😘
♨️本篇文章记录的为 SpringAOP 关键API详解 相关内容,适合在学Java的小白,帮助新手快速上手,也适合复习中,面试中的大佬🙉🙉🙉。
♨️如果文章有什么需要改进的地方还请大佬不吝赐教❤️🧡💛
👨🔧 个人主页 : 阿千弟
🔥 上期内容👉👉👉 : 2023年主流的选择仍是Feign, http客户端Feign还能再战
@[toc]
JoinPoint和ProceedingJoinPoint区别
在Spring AOP中,JoinPoint和ProceedingJoinPoint是两个非常重要的概念,它们都是AOP中的切点。
JoinPoint是指在程序执行过程中,可以插入切面的点。例如,在方法执行前、执行后、抛出异常时等都可以插入切面。JoinPoint包含了当前程序执行的上下文信息,例如方法名、参数、目标对象等。
ProceedingJoinPoint是JoinPoint的子接口,它是在方法执行过程中的某个特定点,例如方法执行前、执行后、抛出异常时等。ProceedingJoinPoint除了包含JoinPoint的所有信息外,还包含了一个proceed()方法,该方法用于执行目标方法。
因此,JoinPoint和ProceedingJoinPoint的区别在于,ProceedingJoinPoint包含了一个proceed()方法,该方法用于执行目标方法,而JoinPoint则不包含该方法。在编写AOP切面时,如果需要在目标方法执行前或执行后做一些处理,可以使用JoinPoint;如果需要在目标方法执行过程中做一些处理,可以使用ProceedingJoinPoint。
ProceedingJoinPoint
ProceedingJoinPoint是Spring AOP中的一个接口,它代表了一个连接点,即被拦截的方法。在AOP中,我们可以通过拦截连接点来实现对方法的增强。
ProceedingJoinPoint接口提供了以下方法:
Object[] getArgs():获取连接点方法的参数数组。
Signature getSignature():获取连接点方法的签名对象。
Object getTarget():获取连接点所在的目标对象。
Object proceed() throws Throwable:执行连接点方法,返回结果。
String toString():打印出连接点的信息。
在AOP中,我们可以通过ProceedingJoinPoint接口的proceed()方法来执行连接点方法,并在方法执行前后进行一些操作,比如记录日志、检查权限等。同时,我们也可以通过getArgs()方法获取连接点方法的参数,通过getTarget()方法获取目标对象,从而实现更加灵活的增强操作。
需要注意的是,如果我们在拦截器中调用了proceed()方法,那么被拦截的方法就会被执行,如果不调用proceed()方法,那么被拦截的方法就不会被执行。因此,在使用ProceedingJoinPoint时,一定要注意调用proceed()方法的时机。
使用
ProceedingJoinPoint包含了连接点的所有信息,包括目标对象、目标方法、方法参数等。
在使用Spring AOP时,我们可以通过ProceedingJoinPoint来获取连接点的信息,并在切面中对目标方法进行增强。具体使用方法如下:
- 在切面方法中声明ProceedingJoinPoint参数。
@Aspect
@Component
public class MyAspect {
@Around("execution(* com.example.demo.service.UserService.*(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 切面逻辑
Object result = joinPoint.proceed(); // 调用目标方法
// 切面逻辑
return result;
}
}
在切面方法中调用ProceedingJoinPoint的proceed()方法来调用目标方法。
可以通过ProceedingJoinPoint的getArgs()方法获取目标方法的参数。
@Around("execution(* com.example.demo.service.UserService.addUser(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs(); // 获取目标方法的参数
// 切面逻辑
Object result = joinPoint.proceed(); // 调用目标方法
// 切面逻辑
return result;
}
- 可以通过ProceedingJoinPoint的getTarget()方法获取目标对象。
@Around("execution(* com.example.demo.service.UserService.addUser(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
Object target = joinPoint.getTarget(); // 获取目标对象
// 切面逻辑
Object result = joinPoint.proceed(); // 调用目标方法
// 切面逻辑
return result;
}
- 可以通过ProceedingJoinPoint的getSignature()方法获取目标方法的签名。
@Around("execution(* com.example.demo.service.UserService.addUser(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
Signature signature = joinPoint.getSignature(); // 获取目标方法的签名
// 切面逻辑
Object result = joinPoint.proceed(); // 调用目标方法
// 切面逻辑
return result;
}
getSignature
总之,ProceedingJoinPoint是Spring AOP中非常重要的一个接口,它提供了丰富的方法来获取连接点的信息,并在切面中对目标方法进行增强。
getSignature()方法是ProceedingJoinPoint接口中的一个方法,用于获取连接点的签名信息。
连接点的签名信息包括方法名、参数类型、返回类型等。通过getSignature()方法可以获取到一个Signature对象,该对象包含了连接点的签名信息。Signature是一个接口,它有两个子接口:MethodSignature和ConstructorSignature。MethodSignature用于表示方法的签名信息,ConstructorSignature用于表示构造函数的签名信息。
在使用getSignature()方法时,需要先将ProceedingJoinPoint对象转换为MethodSignature或ConstructorSignature对象,然后再调用相应的方法获取签名信息。例如,可以使用以下代码获取连接点的方法名:
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String methodName = signature.getName();
在上述代码中,首先将joinPoint对象转换为MethodSignature对象,然后通过getName()方法获取方法名。
除了获取方法名,还可以通过getDeclaringTypeName()方法获取方法所在类的全限定名,通过getParameterTypes()方法获取方法的参数类型数组,通过getReturnType()方法获取方法的返回类型等。
总之,通过getSignature()方法可以获取连接点的签名信息,从而在切面中对连接点进行更加精细的控制和处理。
@Aspect
@Component
@Slf4j
public class XXXAspect {
@Resource
private SaveLogMapper saveLogMapper;
/**
* 设置保存菜单点击记录切入点,在注解的位置切入代码
*/
@Pointcut("@annotation(com.aqd.Log)")
public void saveQueryUserPortraitLogPointCut() {
}
@Before("saveLogPointCut()")
public void saveQueryUserPortraitLog(JoinPoint joinPoint) {
//----------------单纯的知道哪个类哪个方法进的切面,用于记录start add by zxx -------------------------
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
String className = joinPoint.getTarget().getClass().getName();
String methodName = methodSignature.getMethod().getName();
//----------------单纯的知道哪个类哪个方法进的切面,用于记录start add by zxx -------------------------
// 获取RequestAttributes,这个RequestContextHolder是Springmvc提供来获得请求的东西
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
// 从获取RequestAttributes中获取HttpServletRequest的信息
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
//从请求的参数中获取被查询的手机号 add by zxx 2021/09/14
String protraitQueryedNo = request.getParameter("protraitQueryedNo");
JSONObject userInfo = ((JSONObject) JSON.toJSON(request.getSession().getAttribute("userInfo")));
String userId =userInfo.getString("userId");
//userAccessPermissions
String sessionId = request.getSession().getId();
//客户端ip
String clientAddress =request.getRemoteAddr();
//客户端端口
String clientPort = String.valueOf(request.getRemotePort());
//服务端IP
String serverAddress = request.getLocalAddr();
//服务端端口
String serverPort = String.valueOf(request.getLocalPort());
log.info("[saveLog]className:{},methodName:{}-start to saveLog,userId:{},protraitQueryedNo:{}!!",
className, methodName,userId,protraitQueryedNo);
}
}
如果这篇【文章】有帮助到你💖,希望可以给我点个赞👍,创作不易,如果有对Java后端或者对
spring
感兴趣的朋友,请多多关注💖💖💖
👨🔧 个人主页 : 阿千弟