@After 最终通知

97 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情

@After 最终通知

无论目标方法是否抛出异常,该增强均会被执行。

接口方法:

public interface SomeService {\
    String doSome(String name, int age);\
}

方法实现:

@Component\
public class SomeServiceImpl implements SomeService {\
    @Override\
    public String doSome(String name, int age) {\
        System.*out*.println(name+"doSome方法被调用 (主业务方法)");\
        System.*out*.println(1/0);\
        return "abcd";\
    }\
}

定义切面:

@Aspect

@Component

public class MyAspect {

    /**

     * 最终方法的规范

     * 1)访问权限是public

     * 2)切面方法没有返回值void

     * 3)方法名称自定义

     * 4)方法可以没有参数,也可以有,则JoinPoint.

     * 5)使用@After注解

     * 6)参数:value:指定切入点表达式

     */

    @After(value = "execution(* com.bjpowernode.s04.SomeServiceImpl.*(..))")

    public void myAfter(){

        System.out.println("最终通知被执行.............");

    }

}

测试类:

@Test\
public void test01(){\
    ApplicationContext ac = new ClassPathXmlApplicationContext("s04/applicationContext.xml");\
    SomeServiceImpl someService = (SomeServiceImpl) ac.getBean("someServiceImpl");\
    System.*out*.println(someService.getClass());\
    String s = someService.doSome("张三",22);\
    System.*out*.println("在测试类中输出目标方法的返回值---"+s);\
}

运行结果:

image.png

@Pointcut 定义切入点 别名

当较多的通知增强方法使用相同的 execution 切入点表达式时,编写、维护均较为麻烦。

AspectJ 提供了@Pointcut 注解,用于定义 execution 切入点表达式。其用法是,将@Pointcut 注解在一个方法之上,以后所有的 execution 的 value 属性值均可使用该方法名作为切入点。代表的就是@Pointcut 定义的切入点。这个使用@Pointcut 注解的方法一般使用 private 的标识方法,即没有实际作用的方法。

@Aspect

@Component

public class MyAspect {

    /**

     * 最终方法的规范

     * 1)访问权限是public

     * 2)切面方法没有返回值void

     * 3)方法名称自定义

     * 4)方法可以没有参数,也可以有,则JoinPoint.

     * 5)使用@After注解

     * 6)参数:value:指定切入点表达式

     */

    @After(value = "mycut()")

    public void myAfter(){

        System.out.println("最终通知被执行.............");

    }

    @Before(value = "mycut()")

    public void myBefore(){

        System.out.println("前置通知被执行.............");

    }

    @AfterReturning(value = "mycut()",returning = "obj")

    public void myAfterReturning(Object obj){

        System.out.println("后置通知被执行.............");

    }

    //给切入点表达式起别名

    @Pointcut(value = "execution(* com.bjpowernode.s04.SomeServiceImpl.*(..))")

    public void mycut(){}

}

运行结果:

image.png

SpringAOP与AspectJ的区别

image.png