@Aspect运用

列子、

public interface Calculator {
     
     // 加
     public int add(int i,int j);

     // 减
    public int sub(int i,int j);

    // 乘
    public int mul(int i,int j);

    //除
    public int div(int i,int j);
}



     
  @Service
  public class MyMathCalculator implements Calculator {
        @Override
        public int add(int i, int j) {
            int result = i + j;
            return result;
        }

        @Override
        public int sub(int i, int j) {
            int result = i - j;
            return result;
        }

        @Override
        public int mul(int i, int j) {
            int result = i * j;
            return result;
        }

        @Override
        public int div(int i, int j) {
            int result = i / j;
            return result;
        }
    }


              
      /**
       * 如何将这个类(切面类)中的这些方法(通知方法)动态的在目标方法运行的各个位置切入
       *
       *
       */
      @Aspect
      @Component
  public class LogUtils {

    @Pointcut("execution(public int com.atguigu.impl.MyMathCalculator.*(..))")
    public void MyPoint(){};

/**
 *告诉spring每个方法都什么时候运行;
 *
 *  try{
 *      @Before
 *      method.invoke(obj,args);
 *      @AfterReturning
 *  }catch(e){
 *      @AfterThrowing
 *  }finally{
 *      @After
 *  }
 *
 *
 *
 *  5个通知
 * @Before:在目标方法之前运行
 * @After:在目标方法结束之后
 * @AfterReturning:在目标方法正常返回之后
 * @AfterThrowing:在目标方法抛出异常之后运行
 * @Around:环绕
 *
 * //execution(访问权限符  返回值类型  方法签名)
 *
 */

// @Before("execution(public int com.apcstudy.aop.impl.MyMathCalculator.*(..))")
@Before(value = "MyPoint()")
public static  void logStart(JoinPoint joinPoint){
    //获取到目标方法运行是使用的参数
    Object[] args = joinPoint.getArgs();
    //获取到方法签名
    Signature signature = joinPoint.getSignature();
    String name = signature.getName();
    System.out.println("【"+name+"】方法开始执行,用的参数列表【"+ Arrays.asList(args)+"】");
}

/**
 * 告诉Spring这个result用来接收返回值:
 *          returning="result";
 * @param joinPoint
 * @param result
 */
@AfterReturning(value = "execution(public int com.apcstudy..impl.MyMathCalculator.*(..))",returning = "result")
public static void logReturn(JoinPoint joinPoint,Object result){
    System.out.println("【"+joinPoint.getSignature().getName()+"】方法正常执行完成,计算结果是:"+result);
}

/**
 * 细节四:我们可以在通知方法运行的时候,拿到目标方法的详细信息;
 * 1)只需要为通知方法的参数列表上写一个参数:
 * 		JoinPoint joinPoint:封装了当前目标方法的详细信息
 * 2)、告诉Spring哪个参数是用来接收异常
 * 		throwing="exception":告诉Spring哪个参数是用来接收异常
 * 3)、Exception exception:指定通知方法可以接收哪些异常
 *
 * ajax接受服务器数据
 * 	$.post(url,function(abc){
 * 		alert(abc)
 * 	})
 */
@AfterThrowing(value = "execution(public int com.apcstudy..MyMathCalculator.*(..))",throwing = "exception")
public static void logException(JoinPoint joinPoint,Exception exception){
    System.out.println("【"+joinPoint.getSignature().getName()+"】方法执行出现异常了,异常信息是【"+exception+"】:;这个异常已经通知测试小组进行排查");
}

/**
 * Spring对通知方法的要求不严格;
 * 唯一要求的就是方法的参数列表一定不能乱写?
 *      通知方法是Spring利用反射调用的,每次方法调用得确定这个方法的参数表的值;
 *      参数表上的每一个参数,Spring都得知道是什么?
 *      JoinPoint:认识
 *      不知道的参数一定告诉Spring这是什么?
 * @param joinPoint
 * @return
 */
@After("execution(public int com.apcstudy.aop.impl.MyMathCalculator.*(..))")
private int logEnd(JoinPoint joinPoint){
    System.out.println("【"+joinPoint.getSignature().getName()+"】方法最终结束了");
    return 0;
}

}

  public class AOPTest {

      ApplicationContext ioc = new ClassPathXmlApplicationContext("conf/applicationContext.xml");


/**
 * 通知方法的执行顺序;
 *
 *   try{
 *   	@Before
 *   	method.invoke(obj,args);
 *   	@AfterReturning
 *   }catch(){
 *   	@AfterThrowing
 *   }finally{
 *   	@After
 *   }
 *
 * 正常执行:  @Before(前置通知)=====@After(后置通知)====@AfterReturning(正常返回);
 * 异常执行: @Before(前置通知)=====@After(后置通知)===@AfterThrowing(方法异常)
 *
 */


@Ignore
public void test01(){
    //	一定要从容器中拿到目标对象;注意:如果想要用类型,一定要用他的接口类型,不要用本类;
    Calculator calculator = ioc.getBean(Calculator.class);
    calculator.add(2, 12);
}

@Test
public void test02(){
    //	一定要从容器中拿到目标对象;注意:如果想要用类型,一定要用他的接口类型,不要用本类;
    Calculator calculator = ioc.getBean(Calculator.class);
    calculator.add(2, 12);
    System.out.println("=================");
    calculator.div(1, 0);
}

}

上一篇:「HTML+CSS」--自定义加载动画【020】


下一篇:Spring AOP 注解开发