Mybatis 动态 SQL 的执行原理是什么?有哪些常用标签?
解析标签,提取ognl表达式(比如判断a>5)传入参数,访问对象取值,根据结果拼接条件,执行返回结果集
if foreach set
aop原理
核心原理:动态代理和字节码增强
动态代理(运行时增强)
- 通过 JDK 动态代理(基于接口)或 CGLIB(基于子类)在运行时创建代理对象。
- 字节码增强(编译时 / 类加载时增强)
- 在编译阶段(如 AspectJ 的
ajc)或类加载时(如 Java Agent)修改字节码。
应用场景:用于解决系统中横切关注点(如日志、事务、安全等)的复用问题,主要是提高复用增强方法功能(aop将这些横切逻辑与业务逻辑分离,提高了代码的复用性和可维护性,)
spring的三级缓存
bean的五大步骤获取定义,实例化,注入属性,初始化,加入容器(一级缓存)
bean创建,包括实例化(指向内存地址),属性注入和初始化
三级缓存,主要用于解决循环依赖的问题
一级缓存用来存储成品,二级缓存用来存放半成品,三级缓存用存储工厂对象
将 A 的工厂对象(ObjectFactory)放入三级缓存(singletonFactories),工厂的作用是:当需要时返回 A 的早期引用(半成品)。
三级缓存的作用,是在实例化之后、初始化之前,把这个 “半成品 Bean” 暂时存起来,供其他 Bean “提前引用
bean的注入方式:构造器,setter方法(就是写方法) ,字段注入(通过注解@resource ,@Autowired)
@Component public class UserService { private UserRepository userRepository; @Autowired public void setUserRepository(UserRepository userRepository) { this.userRepository = userRepository; } }
使用三级缓存无法解决构造器注入循环依赖的的问题,因为构造器要求的在实例化阶段就要;
而三级缓存则是实例化之后,所以压根就没法放入三级缓存
三级缓存是通过延迟生成代理对象,解决循环依赖的同时保证aop
二级缓存只能存储具体对象(无法解决循环依赖)
a-b-a
创建前先检查,没有则先实例化,并加入三级缓存,a进行实例化之后进行属性注入时,依赖b,又开始检查没有,开始创建b实例化,b属性设置时,需要a,则从三级缓存获取半成品a,放入二级缓存,之后完成b的初始化,并放入一级缓存然后a从一级缓存获取进行初始化,
事务传播
带有事务的a方法调用带有事务的b,b事物应该如何操作
事务的本质就是操作要么全成功要么全失败
required: a 有事务b就加入否则自己创建
requires new 不管a是否有事务,b都新建事务,a事务暂停,b结束a继续
场景:带有requires_new的事务的方法a 调用 默认事务的方法b
a调用b,b根据reruied(默认)规则会加入a的事务,
b调用a,则a会把b事务挂起,b自己新建事务继续执行
总结:主要看被调用的方法(上述场景)
support a有事务b加入,a无事务b不开启事务
not supported a有事务a暂停b以非事务执行a无事务b也不开启
mandatory:b依赖a的事务。没有就报错
never b在非事务下执行,a有事务就报错
nested:嵌套事务,b单独回滚不影响a a回滚影响b