1、在使用springboot写AOP的时候,有个JoinPoint类,用来获取代理类和被代理类的信息。
JointPoint是程序运行过程中可识别的点,这个点可以用来作为AOP切入点。JointPoint对象则包含了和切入相关的很多信息。比如切入点的对象,方法,属性等。我们可以通过反射的方式获取这些点的状态和信息,用于追踪tracing和记录logging应用信息。
# 返回目标对象,即被代理的对象Object getTarget();# 返回切入点的参数Object[] getArgs();# 返回切入点的SignatureSignature getSignature();# 返回切入的类型,比如method-call,field-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(); // 获取目标方法声明类型(public、private、protected)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; }
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)@Documentedpublic @interface AopCache { String key();}
切面类:
@Aspect //标注增强处理类(切面类)@Component //交由Spring容器管理@Order(0) //设置优先级,值越低优先级越高public class MyaspectJ { //定义增强,pointcut连接点使用@annotation(xxx)进行定义 @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