ㅤ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>
输出
输出 |
---|
![]() |
执行流程分析
执行流程分析 |
---|
![]() |
结论: 修改会影响最终的结果
作者介绍
ㅤcoderitl
V1