AOP-五种通知类型

前话:由于网不好大概,导致maven下载依赖很慢且出现问题:导致pom中显示正确且代码导包正常--》但一运行就出错,这让我找了半天的错误 最后我还是手动导包了~ 不然早弄完了 靠
目录:


Action.java

package org.javaboy.aop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author 邓雪松 (づ ̄ 3 ̄)づ)
 * @create 2021-10-26-19-39
 * 这是一个自定义注解
 * 注解的使用范围是:放在method上面
 * 保留到运行的时候还存在
 * 哪个方法上面有Action注解就在哪个方法上增强功能
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Action {
}

JavaConfig.java

package org.javaboy.aop;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * @author 邓雪松 (づ ̄ 3 ̄)づ)
 * @create 2021-10-26-20-07
 */

@Configuration
@ComponentScan
//开启自动代理
@EnableAspectJAutoProxy
public class JavaConfig {
}

LogAspect.java

package org.javaboy.aop;

import org.aopalliance.intercept.Joinpoint;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @author 邓雪松 (づ ̄ 3 ̄)づ)
 * @create 2021-10-26-19-45
 * @Component:代表这是个组件
 * @Aspect:表示这是一个切面
 */
@Component
@Aspect
public class LogAspect {
    /**
     * 前置通知  再目标方法执行之前执行
     * @param joinPoint
     * 就是执行add()方法之前这个方法会打印懂?
     */
    @Before("@annotation(Action)")
    public void before(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        System.out.println(name+"方法开始执行了~");
    }

    /**
     * 后置通知,在目标方法执行之后执行
     * @param joinPoint
     */
    @After("@annotation(Action)")
    public void after(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        System.out.println(name+"方法执行结束了...a");
    }

    /**
     * 返回通知,可以在该方法中获取目标方法的返回值,如果目标方法的返回值为void,则收到null
     * @param joinPoint
     * @param r 返回的参数名称 和这里方法的参数名一一对应
     */
    @AfterReturning(value = "@annotation(Action)",returning = "r")
    public void returning(JoinPoint joinPoint,Integer r){
        String name = joinPoint.getSignature().getName();
        System.out.println(name+"方法返回通知:"+r);
    }

    /**
     * 异常通知,当目标方法抛出异常时,该方法会触发
     * @param joinPoint
     * @param e 异常参数,和方法的参数名一一对应,注意异常的类型
     */
    @AfterThrowing(value = "@annotation(Action)",throwing = "e")
    public void afterThrowing(JoinPoint joinPoint,Exception e){
        String name = joinPoint.getSignature().getName();
        System.out.println(name+"方法异常通知:"+e.getMessage());
    }

    /**
     * 环绕通知,环绕通知是上面四种方法的集大成者,环绕通知的核心类似于在反射中执行方法
     * @param pjp
     * @return
     */
    @Around("@annotation(Action)")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        //这个方法有点类似于method.invoke 方法,我们可以在这个方法的前后分别添加日志,相当于前置/后置通知
        Object proceed = pjp.proceed(new Object[]{5,5});
        return proceed;
    }
}

Main.java

package org.javaboy.aop;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author 邓雪松 (づ ̄ 3 ̄)づ)
 * @create 2021-10-26-20-07
 */
public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
        MyCalculator calculator = ctx.getBean(MyCalculator.class);
        calculator.add(3,4);
        calculator.min(3,4);
    }
}

MyCalculator.java

package org.javaboy.aop;

/**
 * @author 邓雪松 (づ ̄ 3 ̄)づ)
 * @create 2021-10-26-19-30
 */
public interface MyCalculator {
    int add(int a,int b);

    void min(int a,int b);

}

MyCalculatorImpl.java

package org.javaboy.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.springframework.stereotype.Component;

/**
 * @author 邓雪松 (づ ̄ 3 ̄)づ)
 * @create 2021-10-26-19-32
 */
@Component
public class MyCalculatorImpl implements MyCalculator {
    @Action
    public int add(int a, int b) {
//        int x = 1/0;
        System.out.println(a + "+" + b + "=" + (a+b));
        return a + b;
    }
    @Action
    public void min(int a, int b) {
        System.out.println(a + "-" + b + "=" + (a-b));

    }
}

运行结果如下

add方法开始执行了~
5+5=10
add方法返回通知:10
add方法执行结束了...a
min方法开始执行了~
5-5=0
min方法执行结束了...a

完 ~

posted @ 2021-10-26 22:10  ╰(‵□′)╯  阅读(139)  评论(0编辑  收藏  举报