sunny123456

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Spring——AOP中五大通知功能的执行顺序(完全注解开发)

1.前言

Spring大家肯定都用过的,IOC和AOP是它的两大核心,那么这篇文章主要和大家分享一下如果对一个方法声明了切面、添加了五种通知,它们的执行顺序是怎样的呢?

由于之前学Spring的时候写过太多了xml配置了,所以这篇文章采用完全注解开发的方式来实现。


2.项目源码

首先是pom文件,我们添加所需依赖。

  1. <dependency>
  2. <groupId>org.springframework</groupId>
  3. <artifactId>spring-context</artifactId>
  4. <version>5.2.5.RELEASE</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework</groupId>
  8. <artifactId>spring-aspects</artifactId>
  9. <version>5.2.5.RELEASE</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>junit</groupId>
  13. <artifactId>junit</artifactId>
  14. <version>4.11</version>
  15. <scope>test</scope>
  16. </dependency>

接下来我们来一个业务接口以及它的实现类。

  1. package com.szh.service;
  2. /**
  3. *
  4. */
  5. public interface SomeService {
  6. String doSome(String name,Integer age);
  7. }

由于我们不写xml配置,所以需要在业务接口实现类上添加 @Service 注解,通过注解将这个类交给Spring IOC容器管理。 

  1. package com.szh.service.impl;
  2. import com.szh.service.SomeService;
  3. import org.springframework.stereotype.Service;
  4. @Service
  5. public class SomeServiceImpl implements SomeService {
  6. @Override
  7. public String doSome(String name, Integer age) {
  8. //int a = 10 / 0; //用于测试异常通知
  9. System.out.println("业务方法doSome(),创建商品的订单");
  10. return "姓名:" + name + ",年龄:" + age;
  11. }
  12. }

然后是我们的切面类,同上面的业务实现类,也需要使用 @Component 注解将这个类交给Spring IOC容器管理。 

  1. package com.szh.handle;
  2. import org.aspectj.lang.ProceedingJoinPoint;
  3. import org.aspectj.lang.annotation.*;
  4. import org.springframework.stereotype.Component;
  5. @Aspect
  6. @Component
  7. public class MyAspect {
  8. @Before(value = "myPointCut()")
  9. public void myBefore() {
  10. System.out.println("前置通知,在目标方法之前先执行的....");
  11. }
  12. @AfterReturning(value = "myPointCut()", returning = "obj")
  13. public void myAfterReturning(Object obj) {
  14. System.out.println("后置通知,在目标方法之后再执行的(如有异常,则后置通知不会执行).... 目标方法返回值:" + obj);
  15. }
  16. @Around(value = "myPointCut()")
  17. public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable {
  18. System.out.println("环绕通知中前置通知的功能....");
  19. Object obj = joinPoint.proceed();
  20. System.out.println("环绕通知中后置通知的功能....");
  21. return obj;
  22. }
  23. @AfterThrowing(value = "myPointCut()", throwing = "e")
  24. public void myAfterThrowing(Exception e) {
  25. System.out.println("异常通知,在目标方法抛出异常时执行的,异常原因是:" + e.getMessage());
  26. }
  27. @After(value = "myPointCut()")
  28. public void myAfter() {
  29. System.out.println("最终通知,总是会被执行的....");
  30. }
  31. @Pointcut(value = "execution(* com.szh.service.impl.*.do*(..))")
  32. private void myPointCut() {
  33. //无需代码
  34. }
  35. }

最后再来个配置类,在这个配置类中开启要替代xml配置文件的相关功能。

  1. package com.szh.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.ComponentScan;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.context.annotation.EnableAspectJAutoProxy;
  6. /**
  7. *
  8. */
  9. @Configuration
  10. //开启包扫描功能,相当于xml中的 <context:component-scan base-package="com.szh"></context:component-scan>
  11. @ComponentScan(basePackages = "com.szh")
  12. //开启aop自动代理功能,相当于xml中的 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  13. @EnableAspectJAutoProxy
  14. public class MyConfig {
  15. }

最后是测试类。

  1. package com.szh;
  2. import com.szh.config.MyConfig;
  3. import com.szh.service.SomeService;
  4. import org.junit.Test;
  5. import org.springframework.context.ApplicationContext;
  6. import org.springframework.context.annotation.AnnotationConfigApplicationContext;
  7. /**
  8. *
  9. */
  10. public class MyTest {
  11. @Test
  12. public void testAnnotationAop() {
  13. ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
  14. SomeService service = (SomeService) context.getBean("someServiceImpl");
  15. String info = service.doSome("张起灵", 20);
  16. System.out.println(info);
  17. }
  18. }

2.1 无异常的执行结果

2.2 有异常的执行结果

https://blog.csdn.net/weixin_43823808/article/details/125460170
posted on 2022-10-18 13:49  sunny123456  阅读(214)  评论(0编辑  收藏  举报