Spring AOP:为什么@After注释在Java,AspectJ中在@AfterThrowing之后执行?

Artemius-dev:

我正在学习AspectJ注释,并且我认为@After注释在@AfterThrowing注释之前执行。但是,它会在之后执行。为什么?

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Order(2)
public class MyDemoLoggingAspect {

    @After("execution(* com.luv2code.aopdemo.dao.AccountDAO.findAccounts(..))")
    public void afterFinallyFindAccountsAdvice(JoinPoint theJoinPoint) {
        
        // print out which method we are advising on
        String method = theJoinPoint.getSignature().toShortString();
        System.out.println("\n=====>>> Executing @After (finally) on method: " 
                            + method);
    
    }
    
    @AfterThrowing(
            pointcut="execution(* com.luv2code.aopdemo.dao.AccountDAO.findAccounts(..))",
            throwing="theExc")
    public void afterThrowingFindAccountsAdvice(
                    JoinPoint theJoinPoint, Throwable theExc) {
        
        // print out which method we are advising on
        String method = theJoinPoint.getSignature().toShortString();
        System.out.println("\n=====>>> Executing @AfterThrowing on method: " + method);
        
        // log the exception
        System.out.println("\n=====>>> The exception is: " + theExc);
    
    }
    
    @AfterReturning(
            pointcut="execution(* com.luv2code.aopdemo.dao.AccountDAO.findAccounts(..))",
            returning="result")
    public void afterReturningFindAccountsAdvice(
                    JoinPoint theJoinPoint, List<Account> result) {
        
        // print out which method we are advising on 
        String method = theJoinPoint.getSignature().toShortString();
        System.out.println("\n=====>>> Executing @AfterReturning on method: " + method);
                
        // print out the results of the method call
        System.out.println("\n=====>>> result is: " + result);
        
        // let's post-process the data ... let's modify it :-)
        
        // convert the account names to uppercase
        convertAccountNamesToUpperCase(result);

        System.out.println("\n=====>>> result is: " + result);
        
    }

    private void convertAccountNamesToUpperCase(List<Account> result) {

        // loop through accounts

        for (Account tempAccount : result) {
            
            // get uppercase version of name
            String theUpperName = tempAccount.getName().toUpperCase();
            
            // update the name on the account
            tempAccount.setName(theUpperName);
        }

    }

    @Before("com.luv2code.aopdemo.aspect.LuvAopExpressions.forDaoPackageNoGetterSetter()")
    public void beforeAddAccountAdvice(JoinPoint theJoinPoint) {
        
        System.out.println("\n=====>>> Executing @Before advice on method");    
        
        // display the method signature
        MethodSignature methodSig = (MethodSignature) theJoinPoint.getSignature();
        
        System.out.println("Method: " + methodSig);
        
        // display method arguments
        
        // get args
        Object[] args = theJoinPoint.getArgs();
        
        // loop thru args
        for (Object tempArg : args) {
            System.out.println(tempArg);
            
            if (tempArg instanceof Account) {
                
                // downcast and print Account specific stuff
                Account theAccount = (Account) tempArg;
                
                System.out.println("account name: " + theAccount.getName());
                System.out.println("account level: " + theAccount.getLevel());                              

            }
        }
        
    }
    
}

输出示例:

===== >>>以异步方式登录到云

===== >>>执行方法的@Before建议方法:列出com.luv2code.aopdemo.dao.AccountDAO.findAccounts(boolean)true

===== >>>执行API分析

===== >>>在方法上执行@AfterThrowing:AccountDAO.findAccounts(..)

===== >>>>异常是:java.lang.RuntimeException:没汤可吃!!!

===== >>>(最终)在方法:AccountDAO.findAccounts(..)上执行

主程序...捕获到异常:java.lang.RuntimeException:没有汤!

主程序:AfterThrowingDemoApp

空值

RG:

问题的答案在日志语句中。After Advice相当于finally块

===== >>>(最终)在方法:AccountDAO.findAccounts(..)上执行

Before,AfterThrowing和After与以下Java代码类似。

public void advice() {
    before();
    try {
        joinPoint();
    } catch (Exception e) {
        afterThrowing();
    } finally {
        after();
    }
}

private void before() {
    System.out.println("Before");
}

private void after() {
    System.out.println("After");
    
}

private void afterThrowing() {
    System.out.println("After throwing");
    
}

public void joinPoint() {
    System.out.println("Performing API analytics");
    throw new RuntimeException();
}

希望这可以帮助

参考资料

最后块

之后(最后)建议

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在 Spring AOP 或 AspectJ 中拦截带注释的类和方法

Spring-AOP:@After建议和@ AfterThrowing / @ AfterReturning之间的执行顺序

为什么构造函数在Spring AOP中只执行一次

Spring AOP与AspectJ

在Spring中执行注释的顺序

为什么@EnableWs从Spring bean中删除了aop代理

Spring AOP使用AspectJ起作用还是什么?

为什么@Table注释在Spring的CRUD操作中是可选的

Spring AOP执行顺序

Spring AOP和RequestMapping注释

为什么@AfterReturning仅在发生异常后@AfterThrowing之后执行?

我需要使用哪个jar来使用Spring AOP AspectJ注释?

什么是Spring服务注释?

Spring AOP + AspectJ:@AfterReturning 建议在模拟时错误执行(实际执行之前)

@AfterThrowing 在 Spring 中的不同行为

在Spring 2.5中从AOP建议访问带注释的HttpServletRequest

在Spring AOP中获取类级别的注释值

注释Spring AOP AspectJ不能与JSF2视图中使用的Managed Bean中的方法一起使用吗?

使用AspectJ的Spring AOP:加载时间编织

没有Spring AOP的Aspectj入门

通过Spring AOP了解AspectJ样式

使用Spring AOP配置XML的Aspectj

Spring AOP 和 AspectJ 使用相同的方法

通过Spring AOP + Aspectj进行异常处理

为什么AspectJ不编译Spring的@Configurable工作的编译时间?

Java Spring注释属性

Spring MVC中的注释

Spring AOP / AspectJ记录方法的执行时间,但是如何将参数传递给它?(Spring Boot API)

Spring AspectJ从ProceedingJoinPoint获取方法注释