AOP中遇到的问题

在复习AOP的时候发现了一个问题

在使用xml方式配置AOP时候发现了Spring的后置通知和最终通知的顺序问题

正常执行的顺序应该是:
前置通知(before)>>目标方法>>后置通知(after-returning)>>异常通知(after-throwing)>>最终通知(after)
当然后置通知和异常通知只能有一个执行

我在xml的编写顺序没有按照平常那么来,是这么写的,先写的最终通知,最后写的后置通知

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="accountService" class="com.ligong.service.impl.AccountServiceImpl"/>
    <bean id="aspect" class="com.ligong.utils.Aspect"/>
    <!--配置aop-->
    <aop:config>
        <!--全局切入点,可以被多个切面的通知所引用-->
        <!--<aop:pointcut id="globalPointcut" expression="execution(* *..*.*(..))"/>-->
        <!--配置切面-->
        <aop:aspect id="myAspect" ref="aspect">
            <!--配置切入点-->
            <aop:pointcut id="myPointcut" expression="execution(public * com.ligong.service.impl.*.*(..))"/>
            <!--配置的通知的类型,建立通知方法与切入点的关联-->
            <!--配置前置通知-->
            <aop:before method="printLogBefore" pointcut-ref="myPointcut"/>
            <!--配置最终通知-->
            <aop:after method="printLogAfter" pointcut-ref="myPointcut"/>
            <!--配置后置通知-->
            <aop:after-returning method="printLogAfterReturning" pointcut-ref="myPointcut"/>
            

            <!--配置异常通知-->
            <!--<aop:after-throwing method="printLogThrowing" pointcut-ref="myPointcut"/>-->
        </aop:aspect>
    </aop:config>
</beans>

但是按常理来说他执行的顺序应该是这样的
前置通知(before)>>目标方法>>后置通知(after-returning)>>最终通知(after)

ps:下面这个图和我写的代码没啥关系,只是列出这几个通知的先后顺序

在这里插入图片描述
finally中的方法应该是最后执行的
但是我的执行顺序是这样
前置通知(before)>>目标方法>>最终通知(after)>>后置通知(after-returning),后置通知和最终通知的顺序反了
在这里插入图片描述
然后在xml中,把最终通知移到后置通知下面就好了
难道Spring AOP中后置通知和最终通知的执行顺序与XML中通知的先后顺序有关?

应该也是有争议的
在这里插入图片描述

#问题描述:给业务层织入切面后,业务层方法返回控制层后,返回值为null #相关代码: ##controller: @RequestMapping("/queryExample") public Result queryExample(Long id) { Example example = exampleService.findObject(id); System.out.println("ExampleController***"+example); return new Result(example); } ##ExampleServiceImpl: @Override public Example findObject(Long id) { Example example = exampleMapper.selectOne(id); System.out.println("ExampleServiceImpl***"+example); return example; } ##ExampleAspect: /** * 切点方法 */ @Pointcut("execution(* com.seanzhang.sys.service.*.*(..))") public void pointCutDemo() {} /** * 环绕通知方法 * @param jp */ @Around("pointCutDemo()") public void aroundDemo(ProceedingJoinPoint jp) { try { System.out.println("beforeAroundDemo()"); jp.proceed(); System.out.println("afterReturningAroundDemo()"); System.out.println("afterAroundDemo()"); } catch (Throwable e) { System.out.println("afterThrowingAroundDemo()"); System.out.println("afterAroundDemo()"); e.printStackTrace(); } } #控制台 ##没加切面控制台输出: ExampleServiceImpl***Example [id=1, username=张三, password=123456] ExampleController***Example [id=1, username=张三, password=123456] ##加完切面控制台输出: beforeAroundDemo() ExampleServiceImpl***Example [id=1, username=张三, password=123456] afterReturningAroundDemo() afterAroundDemo() ExampleController***null #可以看到,加完切面之后,对象从业务层返回控制层的时候竟然神奇的丢了,不知道有没有大神遇到过类似的问题?怎么解决的?谢谢!
©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页