浅谈@Aspect@Order各个通知的执行顺序

作者:快乐妮子 时间:2021-10-24 19:00:38 

@Aspect@Order各个通知的执行顺序

两个切面类:【记录日志】和【判断参数】,分别对应顺序 @Order(0) 和@Order(1) 。

本文只是将重点说下 执行顺序 这么回事哈哈哈

代码

【业务类】

/**
* 登录控制器
*/
@Controller
public class LoginController {
   //向外面抛出异常
   public void loginWithThrow(String username, String password) throws Exception {
       if (username == null || password == null) {
           throw new Exception("登录信息不可为空啊");
       }
       System.out.println("LoginController#login...");
   }
   //抛出异常自己捕获的情况
   public void loginWithTryCatch(String username, String password) {
      try{
          if (username == null || password == null) {
              throw new Exception("登录信息不可为空啊");
          }
          System.out.println("LoginController#login...");
      }catch (Exception e){
          e.printStackTrace();
      }
   }
}

【切面类】

/**
* 输出日志注解
*/
@Order(0)
@Aspect
@Component
public class LogAspect {
   //抽出共通的execution用的
   //com.yuki.demo.aop.aspect 包或者子包下所有类的方法
   @Pointcut("execution(* com.yuki.demo.aop.aspect..*.*(..))")
   public void pointcut(){
   }
   //前置通知
//    @Before("execution(public void com.yuki.demo.aop.aspect.LoginController.*(String,String))")
   @Before("pointcut()")
   public void before() {
       System.out.println("LogAspect#before...");
   }
   //环绕通知
   //ProceedingJoinPoint 只有环绕通知有
   @Around("execution(public void com.yuki.demo.aop.aspect.LoginController.*(String,String))")
   public void around(ProceedingJoinPoint joinPoint) throws Throwable {
       System.out.println("LogAspectA#around开始...");
       //代理方法的执行,如果没有joinPoint.proceed() ,则前置通知@Before 不会执行,其它的通知正常
       joinPoint.proceed();
       //执行方法之后,如果joinPoint.proceed() 抛出了异常,则该句不会执行,抛出异常后直接跳出了aroud方法了
       System.out.println("LogAspectA#around结束...");
   }
   //后置通知(只要连接点被执行,不管是否抛出异常)
   @After("execution(public void com.yuki.demo.aop.aspect.LoginController.*(String,String))")
   public void after() {
       System.out.println("LogAspect#after...");
   }
   //异常通知(只有在joinPoint.proceed()方法执行向外面抛出了异常,才会执行该通知)
   @AfterThrowing("execution(public void com.yuki.demo.aop.aspect.LoginController.*(String,String))")
   public void afterThrowing() {
       System.out.println("LogAspect#afterThrowing...");
   }
   //正常的返回通知通知(正常结束了才会执行该通知)
   @AfterReturning("execution(public void com.yuki.demo.aop.aspect.LoginController.*(String,String))")
   public void afterReturning() {
       System.out.println("LogAspect#afterReturning...");
   }
}

【切面类】

/**
* 判断请求参数的sign是否正确的 切面类
*/
@Order(1)
@Aspect
@Component
public class SignAspect {
   @Around("execution(public void com.yuki.demo.aop.aspect.LoginController.*(String,String))")
   public void around(ProceedingJoinPoint joinPoint) throws Throwable {
       System.out.println("SignAspect#around开始...");
       joinPoint.proceed();
       System.out.println("SignAspect#around结束...");
   }
}

【启动配置】

省略。。。非重点

【测试类】

@SpringBootTest
class AopApplicationTests {
   @Autowired
   private LoginController loginController;
   @Test
   void contextLoads() {
       loginController.loginWithTryCatch("yuki", "1234");
   }
}

【控制台输出】

LogAspectA#around开始...
LogAspect#before...
SignAspect#around开始...
LoginController#login...
SignAspect#around结束...
LogAspectA#around结束...
LogAspect#after...
LogAspect#afterReturning...

小结

浅谈@Aspect@Order各个通知的执行顺序

浅谈@Aspect@Order各个通知的执行顺序

spring AspectJ order(顺序)

@Aspect
@Order(2)
public class HelloWorldAspectAnnotation {
/**
* JoinPoint接口
* @param joinPoint
*/
/*public interface JoinPoint {
   String toString();         //连接点所在位置的相关信息
   String toShortString();     //连接点所在位置的简短相关信息
   String toLongString();     //连接点所在位置的全部相关信息
   Object getThis();         //返回AOP代理对象
   Object getTarget();       //返回目标对象
   Object[] getArgs();       //返回被通知方法参数列表
   Signature getSignature();  //返回当前连接点签名
   SourceLocation getSourceLocation();//返回连接点方法所在类文件中的位置
   String getKind();        //连接点类型
   StaticPart getStaticPart(); //返回连接点静态部分
}*/

//定义前置通知,注意这里是sayHello2
//使用@Before进行前置通知声明,其中value用于定义切入点表达式或引用命名切入点
@Before(value="execution(* com.boventech..*.sayHello2(..))&& args(param)",argNames="param")
public void beforeAdvice(JoinPoint joinPoint,String param) {
System.out.println(1);
System.out.println("=======================");
System.out.println("===param:" + param);
System.out.println("=======================");
System.out.println(joinPoint.getArgs().length);
System.out.println("=======================");
System.out.println(joinPoint.toString());
System.out.println("=======================");
System.out.println(joinPoint.getTarget());
System.out.println("=======================");
System.out.println(joinPoint.getThis());
System.out.println("=======================");
System.out.println("===========before advice");
}
/*value:指定切入点表达式或命名切入点;
   pointcut:同样是指定切入点表达式或命名切入点,如果指定了将覆盖value属性指定的,pointcut具有高优先级;*/
@AfterReturning(value="execution(* com.boventech..*.sayHello2(..))&& args(param)",argNames="param",pointcut="execution(* com.boventech..*.sayHello2(..))&& args(param)")
public void afterFinallyAdvice(JoinPoint joinPoint,String param) {
System.out.println("param:"+param);
System.out.println("===========");
System.out.println("===========after finally advice");
}
}
@Aspect
@Order(1)
public class HelloWorldAspectAnnotation2 {
/**
* JoinPoint接口
* @param joinPoint
*/
/*public interface JoinPoint {
   String toString();         //连接点所在位置的相关信息
   String toShortString();     //连接点所在位置的简短相关信息
   String toLongString();     //连接点所在位置的全部相关信息
   Object getThis();         //返回AOP代理对象
   Object getTarget();       //返回目标对象
   Object[] getArgs();       //返回被通知方法参数列表
   Signature getSignature();  //返回当前连接点签名
   SourceLocation getSourceLocation();//返回连接点方法所在类文件中的位置
   String getKind();        //连接点类型
   StaticPart getStaticPart(); //返回连接点静态部分
}*/

//定义前置通知,注意这里是sayHello2
//使用@Before进行前置通知声明,其中value用于定义切入点表达式或引用命名切入点
@Before(value="execution(* com.boventech..*.sayHello2(..))&& args(param)",argNames="param")
public void beforeAdvice(JoinPoint joinPoint,String param) {
System.out.println(2);
System.out.println("=======================");
}

/*value:指定切入点表达式或命名切入点;
   pointcut:同样是指定切入点表达式或命名切入点,如果指定了将覆盖value属性指定的,pointcut具有高优先级;*/
@AfterReturning(value="execution(* com.boventech..*.sayHello2(..))&& args(param)",argNames="param",pointcut="execution(* com.boventech..*.sayHello2(..))&& args(param)")
public void afterFinallyAdvice(JoinPoint joinPoint,String param) {
System.out.println("order:" + 2);
}
}
public class AopAnnotationTest {
@Test
   public void testHelloworld() {
       ApplicationContext ctx =  new ClassPathXmlApplicationContext("/helloWorld2.xml");
       IHelloWorld2Service helloworldService =ctx.getBean("helloWorld2Service", IHelloWorld2Service.class);
       String param = "12";
       helloworldService.sayHello2(param);
   }
}
<aop:aspectj-autoproxy/>
<bean id="helloWorld2Service" class="com.boventech.learning.serviceImpl.HelloWorld2ServiceImpl"/>

<bean id="aspect"
            class="com.boventech.learning.aspect.HelloWorldAspectAnnotation"/>

<bean id="aspect2"
            class="com.boventech.learning.aspect.HelloWorldAspectAnnotation2"/>

来源:https://blog.csdn.net/u014240299/article/details/103912843

标签:@Aspect,@Order,通知,执行顺序
0
投稿

猜你喜欢

  • 详解java一维数组及练习题实例

    2023-05-21 17:31:56
  • mybatis中使用oracle关键字出错的解决方法

    2022-05-14 10:19:23
  • JAVA8 十大新特性详解

    2023-07-02 10:03:27
  • SpringBoot使用GraphQL开发Web API实现方案示例讲解

    2023-05-17 16:50:22
  • 基于Spring Boot使用JpaRepository删除数据时的注意事项

    2023-04-03 09:05:39
  • C# Invoke,begininvoke的用法详解

    2023-07-21 01:55:55
  • Mybatis使用@Select注解sql中使用in问题

    2023-01-06 20:52:48
  • 秒懂Kotlin之Java工程师快速掌握Kotlin的技巧

    2023-07-09 21:25:19
  • 为什么Spring官方推荐的@Transational还能导致生产事故

    2022-02-13 15:54:37
  • Java手动实现Redis的LRU缓存机制

    2023-07-31 12:51:30
  • Spring注解配置IOC,DI的方法详解

    2023-10-18 14:06:23
  • ActiveMQ安装及部署教程图解

    2023-11-17 18:01:46
  • Opencv EigenFace人脸识别算法详解

    2023-07-21 19:30:17
  • C#连接ODBC数据源的方法

    2023-04-20 07:30:33
  • java并发JUC工具包AtomicInteger原子整型语法基础

    2023-10-05 14:16:47
  • androidQ sd卡权限使用详解

    2021-09-27 17:38:51
  • Java 数据结构与算法系列精讲之字符串暴力匹配

    2021-10-06 05:43:27
  • android多媒体音乐(MediaPlayer)播放器制作代码

    2022-01-06 01:13:20
  • Spring MVC的优点与核心接口_动力节点Java学院整理

    2023-11-28 05:43:36
  • IDEA离线安装maven helper插件的图文教程

    2023-11-28 16:00:24
  • asp之家 软件编程 m.aspxhome.com