ㅤcoderitl

V1

2022/02/23阅读:43主题:萌绿

spring中在后置通知中修改引用类型的返回值是否影响最后的返回值?

测试

<!-- 依赖 -->
 <dependencies>
        <!-- 单元测试依赖 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!--   spring 依赖     -->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>
        <!--  aspects 框架依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>
    </dependencies>
// 接口定义
package org.coderitl;

public interface SomeService {
    public Student doSome(String name, int age);
}
// 接口实现类
package org.coderitl.impl;

import org.coderitl.SomeService;
import org.coderitl.Student;
import org.springframework.stereotype.Component;

// <bean id="SomeServiceImplAfterRuturning" class="org.coderitl.impl.SomeServiceImpl">
@Component("SomeServiceImplAfterRuturning")
public class SomeServiceImpl implements SomeService {
    @Override
    public Student doSome(String name, int age) {
        Student student = new Student(name, age);
        System.out.println("SomeServiceImpl dome: " + student);
        // SomeServiceImpl dome: Student{name='coder-itl', age=18}
        return student;
    }
}
// 后置通知
package org.coderitl;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;


@Component("myAspectAfter")
@Aspect
public class MyAfterRuturning {
    // execution => 目标方法的表达式
    @AfterReturning(value = "execution(* *..SomeServiceImpl.*(..))", returning = "result")
    public void myAfterRuturning(Object result) {
        // 增强内容代码块
        System.out.println("后置通知执行时student值: " + result);

        if (result != null) {
            // 修改地址指向并不会得到正确的结论(注释掉)
            result = new Student("address"80);
            System.out.println("修改 result 地址指向: " + result);

            // 真正的修改
            Student student = (Student) result;
            System.out.println("后置通知中修改前: " + student);
            student.setName("fixName");
            student.setAge(19);
            System.out.println("后置通知中修改后: " + student);
        }
    }
}
<!-- 配置文件内容 -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       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
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd"
>


    <!--  AfterReturning  -->
    <context:component-scan base-package="org.coderitl"/>

    <!--
     声明自动代理生成器: 使用 aspectj 框架内部的功能,创建目标对象的代理对象
     创建代理对象是在内存中实现的,修改目标对象的内存中的结构
     构建为代理对象,所以目标对象就是被修改后的代理对象

     aspectj-autoproxy: 会把 spring 容器中的所有目标对象,一次性都生成代理对象
     -->

    <aop:aspectj-autoproxy/>

</beans>

输出

输出
输出

执行流程分析

执行流程分析
执行流程分析

结论: 修改会影响最终的结果

分类:

后端

标签:

Java

作者介绍

ㅤcoderitl
V1