AOP概念及使用(2)

AOP概念及使用(2)其余4中通知的实现方式。

承接上一篇AOP前言

本片,我们学习AOP的剩余4种通知的方式。

1.后置通知

后置通知,就是在目标方法执行之后执行切面方法

我们依然使用上文种的目标类和切面类

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

/**
 * 切面类
 */
@Aspect
public class MyAspect {

    @AfterReturning(value = "execution(* com.yuyi.serviec.SomeserviceImpl.doSome())"
                    ,returning = "result")
    public void afterReturning(Object result){
        System.out.println("后置通知,在方法执行之后!");
        System.out.println("这是从切面得到的结果"+result);
    }
}

在这里我们依然用Aspect表明切面类
在增强的方法上使用@AfterReturning通知标签,表明执行时间,该标签有两种属性,一种是大家熟悉的value属性,表明切入点,另一种是returning 属性,表示可以得到目标方法的执行结果,该result必须和传入增强方法的参数名一致。

目标方法

public class SomeserviceImpl implements Someservice {
    @Override
    public String  doSome() {
        System.out.println("someservice的doSome方法!");
        return "这是返回结果!";
    }
}

我们运行测试类
在这里插入图片描述

环绕通知

环绕通知是功能最强的通知,可以在目标方法之前和之后都可以执行。它可以控制目标方法是否执行,也可以修改目标方法的执行结果

切面类

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

/**
 * 切面类
 */
@Aspect
public class MyAspect {

    @Around(value = "execution(* com.yuyi.serviec.SomeserviceImpl.doSome())"
                    )
    public Object myAroung(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
         System.out.println("目标 方法之前!");
         Object result = proceedingJoinPoint.proceed();
         System.out.println("目标方法之后!");
         return  result;
    }
}

在切面类上使用@Around 表示执行时间,使用value表示 切入点的位置,增强方法的参数,其类型为ProceedingJoinPoint,这是一个接口,该接口有proceed方法,可以控制目标函数的执行,从代码种我们可以看出,它继承了JoinPoint的类。即这是与切入点有关的。

package org.aspectj.lang;

import org.aspectj.runtime.internal.AroundClosure;

public interface ProceedingJoinPoint extends JoinPoint {
    void set$AroundClosure(AroundClosure var1);

    Object proceed() throws Throwable;

    Object proceed(Object[] var1) throws Throwable;
}

我们运行测试类
在这里插入图片描述

3.异常通知

该异常通知是在目标类抛出异常的时候执行,该通知方法不是异常的处理程序,异常还是该抛出抛出,该捕捉捕捉。
我们看一次切面类和方法

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

/**
 * 切面类
 */
@Aspect
public class MyAspect {

    @AfterThrowing(value = "execution(* com.yuyi.serviec.SomeserviceImpl.doSome())"
                  ,throwing = "throwable" )
    public void myThrowing(Throwable throwable)  {

        System.out.println("目标方法抛出异常,异常是"+throwable.getMessage());
    }
}

在上文代码中,我们使用AfterThrowing修饰切面方法,该注解有两个属性,一个是切入点执行位置,一个是抛出的异常,该异常的引用名称必须和下文中方法的形参一致

在目标方法中我们手动设置异常,

 public void  doSome() {
        System.out.println("someservice的doSome方法!");
       int a= 10/0;
    }

运行测视类
在这里插入图片描述

4.最终通知

最终通知是一定会执行的通知,不管目标程序是否发生异常,是不是像finally子句。
可以进行资源的回收,内存的释放等工作。

    @After(value = "execution(* com.yuyi.serviec.SomeserviceImpl.doSome())"
                   )
    public void myThrowing()  {

        System.out.println("我是最终通知,可以做资源的回收,内存的释放!");
    }

我们进行测试,结果应该是,出错之后,After修饰的类继续执行!
在这里插入图片描述
看,和结果一模一样。

猜你喜欢

转载自blog.csdn.net/qq_39428182/article/details/105775603
今日推荐