一、JoinPoint类、Proceedingjoinpoint

1、在使用springboot写AOP的时候有个JoinPoint用来获取代理类和被代理类的信息

JointPoint程序运行过程中可识别的点,这个可以用来作为AOP切入点。JointPoint对象包含了和切入相关很多信息比如切入点对象方法属性等。我们可以通过反射方式获取这些点的状态信息用于追踪tracing记录logging应用信息

# 返回目标对象,即被代理对象
Object getTarget();

# 返回切入点的参数
Object[] getArgs();

# 返回切入点的Signature
Signature getSignature();

# 返回切入的类型比如method-callfield-get等等,感觉不重要 
 String getKind();

2、Proceedingjoinpoint 继承了 JoinPoint。是在JoinPoint的基础上暴露proceed 这个方法

环绕通知 = 前置 + 目标方法执行 + 后置通知proceed方法就是用于启动目标方法执行暴露这个方法,就能支持 aop:around 这种切面

Proceedingjoinpoint支持环绕通知@Around,而其他的几种切面需要用到JoinPoint,这也是环绕通知和前置、后置通知方法一个最大区别。这跟切面类型有关

注意
joinpoint.getSignature():获取被增强的方法相关信息
joinpoint.getSignature拿到的对象强转成MethodSignature这个实现类之后,里面的getReturnType()方法可以用来目标方法返回值类型

@Before("customerJoinPointerExpression()")
public void beforeMethod(JoinPoint joinPoint){
    // 前置通知
	joinPoint.getSignature().getName(); // 获取目标方法名
	joinPoint.getSignature().getDeclaringType().getSimpleName(); // 获取目标方法所属类的简单类名
	joinPoint.getSignature().getDeclaringTypeName(); // 获取目标方法所属类的类名
	joinPoint.getSignature().getModifiers(); // 获取目标方法声明类型(publicprivateprotected)
	Object[] args = joinPoint.getArgs(); // 获取传入目标方法的参数返回一个数组
	joinPoint.getTarget(); // 获取被代理的对象
	joinPoint.getThis(); // 获取代理对象自己
}
  // 匹配方法执行连接点方式
    @Around(value = "execution(* *..SomeserviceImpl.Dofirst(..))")
    public Object myAspectJ(ProceedingJoinPoint point) throws Throwable {
      
         //拦截实体类
        Object target = point.getTarget();
        //拦截的方法名称
        String methodName = point.getSignature().getName();
        //拦截的方法参数
        Object[] args = point.getArgs();
        //拦截的放参数类型
        Class[] parameterTypes = ((MethodSignature)point.getSignature()).getMethod().getParameterTypes();

        object = point.proceed(); //目标方法的执行
        return null;
    }

二、AOP环绕通知获取注解信息

1、概念

注解(Annotation)是撰写在原始码中的资讯,可以提供代码以外的额外资讯,本身有其结构,你可以使用工具提取这些结构化讯息。
简单来说注解就是写在程序上方的结构化注释java会按照其结构读取讯息,并且做对应操作
比如@Override注解标注在方法上,在编译期间,java就会检查当前方法是否重载父类的方法,如果没有报错

java自带标准注解
@Override表示当前的方法定义覆盖类中的方法;
@Deprecated表示代码被弃用,如果使用了被@Deprecated注解的代码则编译器将发出警告
@SuppressWarnings表示关闭编译器警告信息

利用上述注解生成自己定义的注解,就像自己定义一个类一样,可以通过@interface创建一个自定义注解。

[@Target]     //限定注解可以标注位置:ANNOTATION_TYPE、CONSTRUCTOR 、FIELD 、LOCAL_VARIABLE 、METHOD 、PACKAGE 、PARAMETER 、TYPE
[@Retention]  //说明了这个注解的存活时间	:SOURCE,CLASS ,RUNTIME
[@Documented] // 将注解中的元素包含到 Javadoc 中去	
[@Inherited]  //子类自动拥有父类的注解	
public @interface [名称] {
     // 元素
     String value() default "hello";
}

【@Retention
RetentionPolicy.SOURCE :注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视;
RetentionPolicy.CLASS :注解只被保留编译进行的时候,它并不会被加载到 JVM 中;
RetentionPolicy.RUNTIME :注解可以保留程序运行时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到注解

2、代码示例

注解:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AopCache 
{
    /**
     * 每个方法唯一key
     */
    String key();
}

切面类:

@Aspect    //标注增强处理类(切面类)
@Component //交由Spring容器管理
@Order(0)  //设置优先级,值越低优先级越高
public class MyaspectJ {

    //定义增强,pointcut连接点使用@annotationxxx)进行定义
    @Pointcut(value = "@annotation(xx.xx.xx.AopCache)")
    public void methodPointcut(){}

    // 匹配方法执行连接点方式
    @Around("methodPointcut()")
    public Object myAspectJ(ProceedingJoinPoint point) throws Throwable {
    
        // 获取方法上的注解
        MethodSignature methodSignature = (MethodSignature) point.getSignature();
        Method method = methodSignature.getMethod();
        AopCache annotation = method.getAnnotation(AopCache.class);
        //获取key
        String key = annotation.key();

        object = point.proceed();   // 1. 目标方法的调用
        return null;
    }
}

方法使用这个注解,则会直接走切面增强

@AopCache(key = "自定义key值")
public String getAllType(){

   return "";
}

原文地址:https://blog.csdn.net/Little_Arya/article/details/129973814

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_48412.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注