百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

JAVA面试之spring篇

bigegpt 2025-04-28 23:31 8 浏览

(搜索总结)该篇总结的不多,还会继续添加!


Spring

什么是三级缓存

Spring 使用三级缓存来解决循环依赖问题。三级缓存分别是:

一级缓存(Singleton Objects)

1、存储已经完全初始化完成的单例 Bean。

2、数据结构:Map<String, Object>,键是 Bean 的名称,值是对应的 Bean 实例。

3、作用:当一个 Bean 已经完全初始化后,它会被放入一级缓存,供后续使用。

二级缓存(Early Singleton Objects)

1、存储提前暴露的、尚未完全初始化的 Bean 实例(即“早期引用”)。

2、数据结构:Map<String, Object>,键是 Bean 的名称,值是 Bean 的早期引用。

3、作用:在 Bean 初始化过程中,如果其他 Bean 需要依赖当前 Bean,Spring 会将当前 Bean 的“早期引用”放入二级缓存,以供其他 Bean 使用。

三级缓存(Singleton Factories)

1、存储用于创建早期引用的工厂对象(ObjectFactory)。

2、数据结构:Map<String, ObjectFactory<?>>,键是 Bean 的名称,值是一个工厂对象。

3、作用:当一个 Bean 尚未完全初始化,但需要被其他 Bean 依赖时,Spring 会通过三级缓存中的工厂对象生成一个“早期引用”,并将其放入二级缓存

Spring如何解决循环依赖问题

Spring使用了三级缓存解决了循环依赖的问题。在populateBean()给属性赋值阶段里面Spring会解析你的属性,并且赋值,当发现,A对象里面依赖了B,此时又会走getBean方法,但这个时候,你去缓存中是可以拿的到的。因为我们在对createBeanInstance对象创建完成以后已经放入了缓存当中,所以创建B的时候发现依赖A,直接就从缓存中去拿,此时B创建完,A也创建完,一共执行了4次。至此Bean的创建完成,最后将创建好的Bean放入单例缓存池中。(非单例的实例作用域是不允许出现循环依赖)

BeanFactory和ApplicationContext的区别

1. BeanFactory是Spring里面最低层的接口,提供了最简单的容器的功能,只提供了实例化对象和拿对象的功能。

2. ApplicationContext应用上下文,继承BeanFactory接口,它是Spring的一各更高级的容器,提供了更多的有用的功能。如国际化,访问资源,载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,消息发送、响应机制,AOP等。

3. BeanFactory在启动的时候不会去实例化Bean,中有从容器中拿Bean的时候才会去实例化。ApplicationContext在启动的时候就把所有的Bean全部实例化了。它还可以为Bean配置lazy-init=true来让Bean延迟实例化

动态代理的实现方式,AOP的实现方式

1. JDK动态代理:利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

2. CGlib动态代理:利用ASM(开源的Java字节码编辑库,操作字节码)开源包,将代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

3. 区别:JDK代理只能对实现接口的类生成代理;CGlib是针对类实现代理,对指定的类生成一个子类,并覆盖其中的方法,这种通过继承类的实现方式,不能代理final修饰的类。

@Transactional错误使用失效场景

1. @Transactional 在private上:当标记在protected、private、package-visible方法上时,不会产生错误,但也不会表现出为它指定的事务配置。可以认为它作为一个普通的方法参与到一个public方法的事务中。

2. @Transactional 的事务传播方式配置错误。

3. @Transactional 注解属性 rollbackFor 设置错误:Spring默认抛出了未检查unchecked异常(继承自 RuntimeException 的异常)或者 Error才回滚事务;其他异常不会触发回滚事务。

4. 同一个类中方法调用,导致@Transactional失效:由于使用Spring AOP代理造成的,因为只有当事务方法被当前类以外的代码调用时,才会由Spring生成的代理对象来管理。

5. 异常被 catch 捕获导致@Transactional失效。

6. 数据库引擎不支持事务。

Spring中的事务传播机制

1. REQUIRED(默认,常用):支持使用当前事务,如果当前事务不存在,创建一个新事务。eg:方法B用REQUIRED修饰,方法A调用方法B,如果方法A当前没有事务,方法B就新建一个事务(若还有C则B和C在各自的事务中独立执行),如果方法A有事务,方法B就加入到这个事务中,当成一个事务。

2. SUPPORTS:支持使用当前事务,如果当前事务不存在,则不使用事务。

3. MANDATORY:强制,支持使用当前事务,如果当前事务不存在,则抛出Exception。

4. REQUIRES_NEW(常用):创建一个新事务,如果当前事务存在,把当前事务挂起。eg:方法B用REQUIRES_NEW修饰,方法A调用方法B,不管方法A上有没有事务方法B都新建一个事务,在该事务执行。

5. NOT_SUPPORTED:无事务执行,如果当前事务存在,把当前事务挂起。

6. NEVER:无事务执行,如果当前有事务则抛出Exception。

7. NESTED:嵌套事务,如果当前事务存在,那么在嵌套的事务中执行。如果当前事务不存在,则表现跟REQUIRED一样。

Spring中Bean的生命周期

Spring框架中,Bean的生命周期指的是从Bean的创建到销毁的一系列过程。这个过程通常涉及到几个关键的步骤,包括Bean的实例化、属性设置、初始化、使用以及销毁。下面详细介绍Spring中Bean的生命周期的主要阶段和相关的配置方法。

1. Bean的创建

当Spring容器启动时,它会根据配置文件(如XML配置、注解配置等)创建并初始化Bean。

2. Bean的实例化

通过构造器创建:当你在类中定义了构造器,并且Spring的配置文件中使用了<bean>标签或者使用了@Component、@Service、@Repository等注解时,Spring会调用这个类的构造器来创建Bean的实例。

通过静态工厂方法:可以通过配置<bean>标签的class属性指定一个静态工厂方法,该方法返回Bean的实例。

通过实例工厂方法:可以通过配置<bean>标签的factory-bean属性指定一个工厂Bean,然后通过factory-method属性指定一个工厂方法。

3. Bean的属性设置

一旦Bean被实例化,Spring会通过依赖注入(Dependency Injection, DI)来设置Bean的属性。这可以通过构造器注入、Setter方法注入或者字段注入等方式实现。

4. Bean的初始化

在Bean的属性被设置之后,Spring会调用一些特定的方法来进行初始化。这可以通过以下几种方式实现:

实现InitializingBean接口:实现afterPropertiesSet()方法。

使用@PostConstruct注解:在方法上添加@PostConstruct注解,该方法将在依赖注入完成后执行。

自定义初始化方法:可以在XML配置文件中使用init-method属性指定一个初始化方法,或者在类上使用@Bean(initMethod="methodName")指定初始化方法名。

5. Bean的使用

一旦Bean被初始化,它就可以被应用程序中的其他组件使用了。

6. Bean的销毁

当Spring容器关闭时,它会管理Bean的销毁过程。这可以通过以下方式实现:

实现DisposableBean接口:实现destroy()方法。

使用@PreDestroy注解:在方法上添加@PreDestroy注解,该方法将在容器销毁Bean之前执行。

自定义销毁方法:可以在XML配置文件中使用destroy-method属性指定一个销毁方法,或者在类上使用@Bean(destroyMethod="methodName")指定销毁方法名。

如下图可以增深理解

Spring的后置处理器

1. BeanPostProcessor:Bean的后置处理器,主要在bean初始化前后工作。(before和after两个回调中间只处理了init-method)

2. InstantiationAwareBeanPostProcessor:继承于BeanPostProcessor,主要在实例化bean前后工作(TargetSource的AOP创建代理对象就是通过该接口实现)

3. BeanFactoryPostProcessor:Bean工厂的后置处理器,在bean定义(bean definitions)加载完成后,bean尚未初始化前执行。

4. BeanDefinitionRegistryPostProcessor:继承于BeanFactoryPostProcessor。其自定义的方法postProcessBeanDefinitionRegistry会在bean定义(bean definitions)将要加载,bean尚未初始化前真执行,即在BeanFactoryPostProcessor的postProcessBeanFactory方法前被调用。

相关推荐

得物可观测平台架构升级:基于GreptimeDB的全新监控体系实践

一、摘要在前端可观测分析场景中,需要实时观测并处理多地、多环境的运行情况,以保障Web应用和移动端的可用性与性能。传统方案往往依赖代理Agent→消息队列→流计算引擎→OLAP存储...

warm-flow新春版:网关直连和流程图重构

本期主要解决了网关直连和流程图重构,可以自此之后可支持各种复杂的网关混合、多网关直连使用。-新增Ruoyi-Vue-Plus优秀开源集成案例更新日志[feat]导入、导出和保存等新增json格式支持...

扣子空间体验报告

在数字化时代,智能工具的应用正不断拓展到我们工作和生活的各个角落。从任务规划到项目执行,再到任务管理,作者深入探讨了这款工具在不同场景下的表现和潜力。通过具体的应用实例,文章展示了扣子空间如何帮助用户...

spider-flow:开源的可视化方式定义爬虫方案

spider-flow简介spider-flow是一个爬虫平台,以可视化推拽方式定义爬取流程,无需代码即可实现一个爬虫服务。spider-flow特性支持css选择器、正则提取支持JSON/XML格式...

solon-flow 你好世界!

solon-flow是一个基础级的流处理引擎(可用于业务规则、决策处理、计算编排、流程审批等......)。提供有“开放式”驱动定制支持,像jdbc有mysql或pgsql等驱动,可...

新一代开源爬虫平台:SpiderFlow

SpiderFlow:新一代爬虫平台,以图形化方式定义爬虫流程,不写代码即可完成爬虫。-精选真开源,释放新价值。概览Spider-Flow是一个开源的、面向所有用户的Web端爬虫构建平台,它使用Ja...

通过 SQL 训练机器学习模型的引擎

关注薪资待遇的同学应该知道,机器学习相关的岗位工资普遍偏高啊。同时随着各种通用机器学习框架的出现,机器学习的门槛也在逐渐降低,训练一个简单的机器学习模型变得不那么难。但是不得不承认对于一些数据相关的工...

鼠须管输入法rime for Mac

鼠须管输入法forMac是一款十分新颖的跨平台输入法软件,全名是中州韵输入法引擎,鼠须管输入法mac版不仅仅是一个输入法,而是一个输入法算法框架。Rime的基础架构十分精良,一套算法支持了拼音、...

Go语言 1.20 版本正式发布:新版详细介绍

Go1.20简介最新的Go版本1.20在Go1.19发布六个月后发布。它的大部分更改都在工具链、运行时和库的实现中。一如既往,该版本保持了Go1的兼容性承诺。我们期望几乎所...

iOS 10平台SpriteKit新特性之Tile Maps(上)

简介苹果公司在WWDC2016大会上向人们展示了一大批新的好东西。其中之一就是SpriteKitTileEditor。这款工具易于上手,而且看起来速度特别快。在本教程中,你将了解关于TileE...

程序员简历例句—范例Java、Python、C++模板

个人简介通用简介:有良好的代码风格,通过添加注释提高代码可读性,注重代码质量,研读过XXX,XXX等多个开源项目源码从而学习增强代码的健壮性与扩展性。具备良好的代码编程习惯及文档编写能力,参与多个高...

Telerik UI for iOS Q3 2015正式发布

近日,TelerikUIforiOS正式发布了Q32015。新版本新增对XCode7、Swift2.0和iOS9的支持,同时还新增了对数轴、不连续的日期时间轴等;改进TKDataPoin...

ios使用ijkplayer+nginx进行视频直播

上两节,我们讲到使用nginx和ngixn的rtmp模块搭建直播的服务器,接着我们讲解了在Android使用ijkplayer来作为我们的视频直播播放器,整个过程中,需要注意的就是ijlplayer编...

IOS技术分享|iOS快速生成开发文档(一)

前言对于开发人员而言,文档的作用不言而喻。文档不仅可以提高软件开发效率,还能便于以后的软件开发、使用和维护。本文主要讲述Objective-C快速生成开发文档工具appledoc。简介apple...

macOS下配置VS Code C++开发环境

本文介绍在苹果macOS操作系统下,配置VisualStudioCode的C/C++开发环境的过程,本环境使用Clang/LLVM编译器和调试器。一、前置条件本文默认前置条件是,您的开发设备已...