tx:事务控制,哪些失效,哪些不失效
boot1->boot2底层spring版本对应spring4->spring5
1 spring aop顺序
1.1 AOP常用注解
@Before:前置通知:目标方法之前执行
@After:后置通知:目标方法之后执行(始终执行)
@AfterrReturning:返回后通知:执行方法结束前执行(异常不执行)
@AfterThrowing:异常通知:出现异常时执行
@Around:环绕通知:环绕目标方法执行
1.2 业务类
1.2.1 接口CalcService
public interface CalcService {
public int div(int x, int y);
}
1.2.2 接口实现类CalcServiceImpl新加@Service
@Service
public class CalcServiceImpl implements CalcService {
@Override
public int div(int x, int y) {
int result = x / y;
System.out.println("=======CalcServiceImpl被调用了, 我们的计算结果是: " + result);
return result;
}
}
1.2.3 在除法方法前后置入各种通知,引入切面编程
@Aspect
@Component
public class MyAspect {
@Before("execution(public int com.demo.a20_spring.aop.CalcServiceImpl.*(..))")
public void beforeNotify() {
System.out.println("********@Before我是前置通知MyAspect");
}
@After("execution(public int com.demo.a20_spring.aop.CalcServiceImpl.*(..))")
public void afterNotify() {
System.out.println("********@After我是后置通知");
}
@AfterReturning("execution(public int com.demo.a20_spring.aop.CalcServiceImpl.*(..))")
public void afterReturningNotify() {
System.out.println("********@AfterReturning我是返回后通知");
}
@AfterThrowing("execution(public int com.demo.a20_spring.aop.CalcServiceImpl.*(..))")
public void afterThrowingNotify() {
System.out.println("********@AfterThrowing我是异常通知");
}
@Around("execution(public int com.demo.a20_spring.aop.CalcServiceImpl.*(..))")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object proceed = null;
System.out.println("********我是环绕通知之前AAA");
proceed = proceedingJoinPoint.proceed();
System.out.println("********我是环绕通知之后BBB");
return proceed;
}
}
1.3 新建一个切面类MyAspect并为切面类新增两个注解
1.3.1 @Aspect
指定一个类为切面类
1.3.2 @Component
纳入spring容器管理
1.3.3 DEMO 顺序测试
springboot 1.5.9测试代码:
pom文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 从 Spring Boot 继承默认配置 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<!-- <version>2.3.3.RELEASE</version>-->
</parent>
<groupId>org.example</groupId>
<artifactId>test_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- 1.5.9 spring log start -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.3</version>
</dependency>
<!-- 1.5.9 spring log end -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestAop {
@Resource
private CalcService calcService;
@Test
public void testAop4() {
System.out.println("spring版本: " + SpringVersion.getVersion() + "springboot版本: "+ SpringBootVersion.getVersion());
System.out.println();
System.out.println(calcService.div(10,2));
//异常代码
//System.out.println(calcService.div(10,0));
}
}
正常执行
异常执行
由此得出结论:
正常执行:
@Before(前置通知)--->@After(后置通知)--->@AfterReturning(正常返回)
异常执行:
@Before(前置通知)--->@After(后置通知)--->@AfterThrowing(异常返回)
springboot 2.3.3 测试:
@SpringBootTest
public class TestAop {
@Resource
private CalcService calcService;
@Test
public void testAop5() {
System.out.println("spring版本: " + SpringVersion.getVersion() + "springboot版本: "+ SpringBootVersion.getVersion());
System.out.println();
System.out.println(calcService.div(10,2));
//异常代码
//System.out.println(calcService.div(10,0));
}
}
注解减少
输出结果
异常情况输出
发现顺序改了,spring5开始,After放最后执行
两个版本对比图
2 spring循环依赖
2.1 面试题
2.2 什么是循环依赖
多个bean之间相互依赖,形成了闭环,例如下图:
通常来说,spring容器内部如何解决循环依赖,一般是指默认的单例Bean中,属性互相引用的场景。如下图:
循环依赖官方说明:
如果使用构造方法注入,可能会出现无法解决的循环依赖问题,
假设A需要B注入,B也需要A注入,通过构造方法注入,运行不成立,会报异常。
推荐用setter注入,可支持循环依赖。
2.3 循环依赖注入的影响
demo-SETTER方式
更改为prototype后
顺序分别是一级 三级 二级
3 循环依赖DEBUG
3.1 3个Map和四大方法,总体相关对象
从spring中得到单例bean,用getSingleton, 若是没有,通过doCreateBean创建,populationBean填充,填充完通过addSingleton添加。
3.2 AB两对象在三级缓存中的迁移说明(创建过程)
spring中以do开头的方法是业务代码,做实事的。
3.3 DEBUG步骤。解决循环依赖
全部断点
其他问题:
4 总结
5 参考文献
以上内容均来自下方视频,博客内容仅用于个人学习笔记记录