sunny123456

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  1796 随笔 :: 22 文章 :: 24 评论 :: 226万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

SpringBoot应用AOP及各注解的执行顺序

首先第一步,POM引入jar

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>
 
		<dependency>
			<groupId>aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.5.3</version>
		</dependency>

第二步随便写一个类,然后类中写一个方法,我这里是写了一个除法运算:

public class MathCalculator {
 
    public int div (int i, int j) {
        System.out.println("MathCalculator.div...");
        return i / j;
    }
}

第三步写一个切面类:

//该注解表示声明该类为一个切面类
@Aspect
public class LogAspects {
 
    //定义一个切点,表达式可以灵活运用,我这个表达式是表示MathCalculator类中所有的方法都进行切入
    @Pointcut("execution(public int com.example.demo.aop.MathCalculator.*(..))")
    public void pointCut () {}
 
    //方法执行开始之前
    @Before("pointCut()")
    public void logStart (JoinPoint joinPoint) {
        System.out.println("除法运行...参数:{"+ Arrays.asList(joinPoint.getArgs())+"}");
    }
 
    //方法执行开始之后
    @After("pointCut()")
    public void logEnd (JoinPoint joinPoint) {
        System.out.println("除法结束..." + joinPoint.getSignature().getName());
    }
 
    //当方法进行返回的时候,returning属性是指定方法参数中的result来接收返回参数,这样就可以修改返回参数
    @AfterReturning(value = "pointCut()", returning = "result")
    public void logReturn (JoinPoint joinPoint, Object result) {
        System.out.println("除法正常返回... 返回结果:{"+result+"}");
    }
 
    //当方法执行异常的时候,throwding是指定方法参数中的e来接收异常参数,可以查看发生的什么异常
    @AfterThrowing(value = "pointCut()", throwing = "e")
    public void logException (JoinPoint joinPoint, Exception e) {
        System.out.println("异常... 异常信息:{"+e+"}");
    }
 
    //环绕通知
    @Around("pointCut()")
    public Object logAround (ProceedingJoinPoint joinPoint) throws Throwable {
        //原方法执行之前会打印这个日志
        System.out.println("环绕通知...  开始");
        //执行原方法
        Object obj = joinPoint.proceed();
        //原方法执行结束,打印这行日志
        System.out.println("环绕通知...  结束");
        //返回方法返回参数
        return obj;
    }
}

这里要注意一下AOP注解执行的先后顺序

环绕通知...  开始
除法运行...参数:{[1, 1]}
MathCalculator.div...
环绕通知...  结束
除法结束...div
除法正常返回... 返回结果:{1}
 

运行的顺序是

1、@Around

2、@Before

3、原方法

4、@Around

5、@After

6、@AfterReturning

第四步,写一个配置类,记得一定要加@EnableAspectJAutoProxy注解

//该配置类是为了将我们前2个类(切面类、被切面类)加入到Spring容器中
@Configuration
//启动AOP(一定要加这个注解,切记!!!)
@EnableAspectJAutoProxy
public class SpringOfAOPConfig {
 
    @Bean
    public MathCalculator mathCalculator () {
        return new MathCalculator();
    }
 
    @Bean
    public LogAspects logAspects () {
        return new LogAspects();
    }
 
}

第五步,测试:

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
 
	@Test
	public void contextLoads() {
	    //根据配置类获取SPring容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringOfAOPConfig.class);
        //从容器中获取Bean
        MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
        //执行除法运算
        mathCalculator.div(1, 1);
        //关闭容器
        applicationContext.close();
    }
 
}

 

 

正常结果:

2018-12-11 11:01:25.496  INFO 16364 --- [           main] com.example.demo.DemoApplicationTests    : Started DemoApplicationTests in 3.455 seconds (JVM running for 4.972)
环绕通知...  开始
除法运行...参数:{[1, 1]}
MathCalculator.div...
环绕通知...  结束
除法结束...div
除法正常返回... 返回结果:{1}
2018-12-11 11:01:25.807  INFO 16364 --- [       Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'

异常结果:

2018-12-11 11:11:22.205  INFO 9628 --- [           main] com.example.demo.DemoApplicationTests    : Started DemoApplicationTests in 3.532 seconds (JVM running for 4.559)
环绕通知...  开始
除法运行...参数:{[1, 0]}
MathCalculator.div...
除法结束...div
异常... 异常信息:{java.lang.ArithmeticException: / by zero}
 
java.lang.ArithmeticException: / by zero

看到没:

发生异常的时候@Around的方法执行后切入没有进行,但是@After的方法却执行了,所以原方法发生异常后顺序就是

1、@Around

2、@Brfore

3、原方法

4、@After

5、@AfterThrowing

 

https://blog.csdn.net/wangyijie521/article/details/84951558
posted on   sunny123456  阅读(818)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示