JAVA面试专题-框架篇(Spring+Mybatis)

embedded/2024/9/22 14:46:50/

Spring

Spring框架中的单例bean是线程安全的吗?

bean上面可以加入注解@Scope,如果是singleton(默认),意味着bean在每个spring IOC容器中只有一个实例;如果是prototype,说明一个bean定义可以有多个实例。spring框架没有对单例bean进行任何多线程的封装处理,关于单例bean的线程安全和并发安全需要开发者考虑

AOP

面向切面编程,将与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取封装成一个可重用的模块称为切面,减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。

核心:使用aop中的环绕通知+切点表达式,通过环绕通知的参数获取请求方法的参数(类、方法、注解、请求方式等),获取到这些参数以后,保存到数据库。

Spring事务本质就是通过AOP功能,对方法前后进行拦截,在执行方法之前开启事务,在执行完目标方法之后根据执行情况提交事务或者回滚。

Spring中事务失效的场景有哪些?

异常捕获处理:解决办法抛出异常
抛出检查异常(不是runtime):解决办法,在transactional中配置rollbackFor属性Exception
非public方法:改为public方法

Spring的Bean的生命周期

BeanDefinition:spring容器在进行实例化时,会将xml配置的bean的信息封装成一个BeanDefinition对象,根据这个对象来创建Bean对象,里面有很多属性描述Bean,如beanClassName:bean类名
initMethodName:初始化方法名
properryValues:bean的属性值
scope:作用域
lazyInit:延迟初始化

1. 通过BeanDefinition获取bean的定义信息
2. 调用构造函数实例化bean

3. bean的依赖注入
4. 处理Aware接口(BeanNameAware,BeanFactoryAware,ApplicationContextAware)
5. bean的后置处理器BeanPostProcessor-前置
6. 初始化方法(InitializingBean,init_method)
7. bean的后置处理器BeanPostProcessor-前置(AOP,动态代理等)
8. bean销毁destory

Spring中的循环引用

Spring的循环依赖

 三级缓存

一级缓存:singletonObjects:单例池,缓存已经经历了完整的生命周期,已经初始化完成的bean对象。
二级缓存:earlySingletonObjects:缓存早起的bean对象(生命周期还没走完)。
三级缓存:singletonFactories:缓存的是ObjectFactory,表示对象工厂,用来创建某个对象的。

一级缓存作用:限制bean在beanFactory中只存一份,即实现singleton scope,解决不了循环依赖。
实例化A,先在堆内开辟内存空间得到半成品A,看到了b要设置b属性,因为b是B类型的对象,需要到spring容器查找对象,由于没有B,所以实例化B,在堆内开辟空间得到半成品B,之后初始化B,设置a属性后需要初始化A,造成循环。

 二级缓存:做中间人

实例化A后得到原始对象A以后放入到二级缓存中(半成品),此时需要注入B,所以实例化B,得到一个原始对象B也放入到二级缓存中,此时需要注入A,从二级缓存中即可获取A,B创建成功注入给A,A也创建成功,放入到一级缓存中。

 三级缓存:代理对象

实例化A,原始对象A生成一个ObjetFactory对象放入到三级缓存中,此时需要注入B所以进行实例化,生成一个objectfactory的b对象放入三级缓存,需要注入A,之后从三级缓存中拿到A的objectfactory对象创建代理对象放到二级缓存中,同时注入给B,后面一致。

 如果构造方法中产生了循环依赖,由于bean的生命周期中构造函数是第一个执行的,spring框架并不能解决构造函数的依赖注入。在后面加入@Lazy注解进行懒加载,什么时候需要对象再进行bean对象的创建。

SpringMVC的执行流程

1. 用户发送出http请求到前端控制器DispatcherServiet
2. DispatcherServiet接收到请求调用处理器映射器HandlerMapping
3. HandlerMapping找到具体的处理器,生成处理器对象以及处理器拦截器,再一起返回给DispatcherServiet
4. DispatcherServiet调用处理器适配器HandlerAdapter
5. HandlerAdapter经过适配器调用具体的处理器(Handler/Controller)
6. 方法上添加了@ReaponseBody
7. 通过HttpMessageConverter来返回结果转换为JSON并响应

SpringBoot自动配置原理

@SpringBootApplication=
@SpringBootConfiguration:声明当前类是一个配置类
@ComponentScan:组件扫描当前引导类所在包及其子包
@EnableAutoConfiguration:SpringBoot实现自动化配置的核心注解

 其通过@Import注解注入导入对应的配置选择器,读取该项目和该项目引用的jar包的classpath路径下META-INF/spring.factories文件中的所配置类的全类名,在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入到Spring容器中。条件判断会有像@ConditionalOnClass这样的注解,判断是否有对应的class文件,如果有则加载该类,把这个配置类所有的Bean放入spring容器中使用。

Spring常见注解

 

Mybatis

Mybatis执行流程

1. 读取MyBatis配置文件:mybatis-config.xml加载运行环境和映射文件
2. 构建会话工厂SqlSessionFactory
3. 会话工厂创建SqlSession对象(包含了执行SQL语句的所有方法)
4. 操作数据库接口,Executor执行器,同事负责查询缓存的维护
5. Executor接口的执行方法中有一个MappedStatement类型的参数,封装了映射信息
6. 输入参数映射:从java类型到sql类型
7. 输出结果映射:从sql转为jave类型

Mybatis延迟加载

查询用户的时候,把用户所属的订单数据也查询出来,这个是立即加载
查询用户的时候,暂时不查询订单数据,当需要订单的时候,再查询订单,这个就是延迟加载

延迟加载原理:

1. 使用CGLIB创建目标对象的代理对象
2. 当调用目标方法时,进入拦截器的invoke方法,发现目标方法是null,执行sql查询
3. 获取数据后,调用set方法设置属性值,再继续查询方法,就有值了

Mybatis一级二级缓存

一级缓存:基于PerpetualCache的HashMap本地缓存,其存储作用域为Session,当Session进行flush或者close后,Cache清空,默认打开一级缓存
二级缓存;基于namespace和mapper的作用域起作用,不依赖session,默认也是采用perpetualcache,hashmap存储,需要单独开启,一个是核心配置,一个是mapper映射文件

二级缓存清理数据:当某个作用域(一级缓存session/二级缓存namespace)进行了增删改后,默认该作用域所有select中的缓存被clear。


http://www.ppmy.cn/embedded/29826.html

相关文章

【亲测有效】Element UI 自定义 Notification 通知样式不生效,设置this.$notify样式不生效问题

不生效的源代码 <style lang"scss" scoped> ::v-deep .el-notification__group {margin-left: 130px; } </style><style lang"scss" scoped> .el-notification__group {margin-left: 130px; } </style>以上两种代码均不生效 解决…

【跟马少平老师学AI】-【神经网络是怎么实现的】(九)长短期记忆网络

一句话归纳&#xff1a; 1&#xff09;RNN也会存在梯度消失的问题。 2&#xff09;同一句话&#xff0c;对于不同的任务&#xff0c;句中不同的词起的作用也不一样。 3&#xff09;LSTM&#xff08;长短期记忆&#xff09;子网络&#xff1a; 门&#xff0c;让输入经过运算&…

React Router 路由配置数组配组持久化

在一些特定场景下,你可能需要将路由配置数组进行持久化,例如从后端动态加载路由配置或根据用户权限动态生成路由配置。这时,持久化路由配置数组就很有用,可以避免每次应用启动时重新获取或计算路由配置。 持久化路由配置数组的步骤如下: 定义路由配置数组 首先,你需要定义一…

Redis__事务

文章目录 &#x1f60a; 作者&#xff1a;Lion J &#x1f496; 主页&#xff1a; https://blog.csdn.net/weixin_69252724 &#x1f389; 主题&#xff1a;Redis__事务 ⏱️ 创作时间&#xff1a;2024年05月02日 ———————————————— 这里写目录标题 文章目…

【软件工程】需求分析

目录 前言需求分析UML概述用例图用例图的组成用例图中的符号和含义包含的两种使用场景 用例图补充&#xff1a;“系统”用例模型建模确定系统参与者确定系统用例 用例文档用例文档组成部分 活动图组成元素初始节点和终点活动节点转换决策与分支、合并分岔与汇合 类图类的表示类…

阿里云CentOS7 打开/关闭防火墙 开放端口

#查看防火墙状态# systemctl status firewalld #关闭防火墙# systemctl stop firewalld #打开防火墙# systemctl start firewalld #添加开放2375端口# firewall-cmd --add-port2375/tcp --permanent #重载入添加的端口# firewall-cmd --reload #查询2375端口是否开启成…

ssh远程访问windows系统下的jupyterlab

网上配置这一堆那一堆&#xff0c;特别乱&#xff0c;找了好久整理后发在这里 由于既想打游戏又想做深度学习&#xff0c;不舍得显卡性能白白消耗&#xff0c;这里尝试使用笔记本连接主机 OpenSSH 最初是为 Linux 系统开发的&#xff0c;现在也支持包括 Windows 和 macOS 在内…

Nacos的开源背景与主要贡献者深度解析

在当前的软件架构领域&#xff0c;微服务架构凭借其高度的可扩展性、灵活性和可维护性&#xff0c;已成为企业构建复杂应用的首选。而在这个领域&#xff0c;Nacos作为一个由阿里巴巴推出的开源项目&#xff0c;其影响力日益增强&#xff0c;成为了众多开发者构建和管理微服务架…