无论目标方法是否正常执行,最终通知的代码都会被执行

最终通知与try..catch..finally中的finally相近

代码

业务接口

  1. package com.chentianyu.s04;
  2. public interface {
  3. String doSome(String name,int age);
  4. }

业务接口的实现类

  1. package com.chentianyu.s04;
  2. import org.springframework.stereotype.Service;
  3. @Service
  4. public class SomeServiceImpl implements SomeService {
  5. @Override
  6. public String doSome(String name, int age) {
  7. System.out.println("doSome业务方法被执行了..."+name);
  8. return "abcd";
  9. }
  10. }

切面类(最终通知)

  1. package com.chentianyu.s04;
  2. import org.aspectj.lang.annotation.After;
  3. import org.aspectj.lang.annotation.Aspect;
  4. import org.springframework.stereotype.Component;
  5. @Aspect
  6. @Component
  7. public class MyAspect {
  8. /**
  9. * 最终通知的规范
  10. * 1.访问权限是public
  11. * 2.方法没有返回值
  12. * 3.方法名称自定义
  13. * 4.方法没有参数,如果有也只能是JoinPoint(前置通知说过有JoinPoint,它必须是整个参数的第一个)
  14. * 5.使用@After注解,表明是最终通知
  15. * value: 指定切入点表达式
  16. */
  17. @After(value = "execution(* com.chentianyu.s04.*.*(..))")
  18. public void myAfter(){
  19. System.out.println("最终通知的功能...");
  20. }
  21. }

这里只是代码格式,在开发中并不是只有一条输出语句,而是有复杂的业务逻辑

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
  6. <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  7. <context:component-scan base-package="com.chentianyu.s04" />
  8. </beans>
@Test
public void test04(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("s04/applicationContext.xml");
    com.chentianyu.s04.SomeService someService = (com.chentianyu.s04.SomeService) applicationContext.getBean("someServiceImpl");//接口的实现类名称
    String s = someService.doSome("张三", 22);
    System.out.println("在测试方法中的目标方法返回值:" + s);
}
doSome业务方法被执行了...张三
最终通知的功能...
在测试方法中的目标方法返回值:abcd

后置通知与其他通知的区别

最终通知中的SomeServiceImpl.java

package com.chentianyu.s04;

import org.springframework.stereotype.Service;

@Service
public class SomeServiceImpl implements SomeService {
    @Override
    public String doSome(String name, int age) {
        System.out.println("doSome业务方法被执行了..."+name);
        System.out.println(1/0);//添加了这条
        return "abcd";
    }
}
doSome业务方法被执行了...张三
最终通知的功能...

java.lang.ArithmeticException: / by zero

但是最终同时依然运行了,在return前报的这个错


后置通知中的SomeService.java

@Override
public String doSome(String name, Integer age) {
    System.out.println("doSome方法被执行了...");
    System.out.println(1/0);//修改了这条
    return "abcd";
}

得到的结果:

doSome方法被执行了...

java.lang.ArithmeticException: / by zero

只有目标方法被执行,目标方法被阻止

总结

以上就是最终通知和其他通知的区别。最终通知: **不管你运行是有没有报错,都会让你顺利的执行通知中的内容**