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

说实话,面试这么问Spring框架的问题,我真扛不住

ccwgpt 2024-11-05 09:42 45 浏览 0 评论


面试官:Spring Framework有用过吧?

小小白:用过(有些心虚,因为Spring框架中内容太多了)。

面试官:在applicationgContext.xml文件中定义了一个bean,id为authService,通过ApplicationContext实例对象的getBean方法获取到这个bean,这个背后的实现原理是什么?

小小白:(心想得谨慎回答,因为可能会把自己带进坑里)Spring容器启动的时候会解析applicationgContext.xml,将xml中定义的bean(如authService)解析成Spring内部的BeanDefinition,并以beanName(如authService)为key,BeanDefinition(如authService相应的BeanDefinition)为value存储到DefaultListableBeanFactory中的beanDefinitionMap属性中(其实它就是一个ConcurrentHashMap类型的属性),同时将beanName存入beanDefinitionNames中(List类型),然后遍历beanDefinitionNames中的beanName,进行bean的实例化并填充属性,在实例化的过程中,如果有依赖没有被实例化将先实例化其依赖,然后实例化本身,实例化完成后将实例存入单例bean的缓存中,当调用getBean方法时,到单例bean的缓存中查找,如果找到并经过转换后返回这个实例(如AuthService的实例),之后就可以直接使用了。

面试官:说一下xml文件的解析过程?

小小白:代码中指定要加载的xml文件后,Spring容器初始化的过程中,通过ResourceLoader接口实现类,例如ClassPathXmlApplicationContext,将xml文件路径转换成对应的Resource文件,例如ClassPathResource,然后通过DocumentLoader对Resource文件进行转换,转换成Document文件,接着通过DefaultBeanDefinitionDocumentReader对Document进行解析,并使用BeanDefinitionParserDelegate对元素进行解析,解析xml中bean定义的各个元素,存入BeanDefinition中。

面试官:那你再详细说一下这个BeanDefinition是什么?

小小白:一个对象的生命周期要想被Spring容器管理,那么它的类信息必须先转成Spring内部的数据结构,BeanDefinition就是Spring框架内部用来描述对象的类信息的数据结构。例如类名、scope、属性、构造函数参数列表、依赖的bean、是否是单例类、是否是懒加载等,其实就是将Bean的定义信息存储到这个BeanDefinition相应的属性中,后面对Bean的操作就直接对BeanDefinition进行,例如拿到这个BeanDefinition后,可以根据里面的类名、构造函数、构造函数参数,使用反射进行对象创建。BeanDefinition是一个接口,是一个抽象的定义,实际使用的是其实现类,如ChildBeanDefinition、RootBeanDefinition、GenericBeanDefinition等。BeanDefinition继承了AttributeAccessor,说明它具有处理属性的能力;BeanDefinition继承了BeanMetadataElement,说明它可以持有Bean元数据元素,作用是可以持有XML文件的一个bean标签对应的Object。

面试官:刚刚你有说到DefaultListableBeanFactory,它在Spring框架中的作用是什么?

小小白:DefaultListableBeanFactory是整个Bean加载的核心部分,是Spring注册及加载Bean的默认实现。DefaultListableBeanFactory间接实现了BeanFactory接口,而在BeanFactory接口中定义了很多和bean操作相关的方法,例如getBean、containsBean、isSingleton等,所以DefaultListableBeanFactory也相应持有了这些操作。

面试官:那BeanFactory又是什么?

小小白:BeanFactory是用于访问Spring Bean容器的根接口,是一个单纯的Bean工厂,也就是常说的ioc容器的顶层定义,各种ioc容器是在其基础上为了满足不同需求而扩展的,包括经常使用的ApplicationContext。

面试官:如何理解BeanFactory和FactoryBean?

小小白:BeanFactory定义了ioc容器的最基本形式,并提供了ioc容器应遵守的的最基本的接口,也就是Spring ioc所遵守的最底层和最基本的编程规范,它只是个接口,并不是ioc容器的具体实现。它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。再来说说FactoryBean,一般情况下,Spring通过反射机制利用bean的class属性实例化Bean,然而在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在bean的定义中提供大量的配置信息,而配置这种方式的灵活性是受限的,这时采用编码的方式可能会是一个比较合适的方案,Spring为此提供了FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。

面试官:如果想在初始化前修改bean的属性,如何实现?

小小白:自定义一个BeanFactoryPostProcessor,让它实现BeanFactoryPostProcessor接口,并实现postProcessBeanFactory方法,在这个方法中可以在初始化前修改bean的属性。

面试官:这个自定义的BeanFactoryPostProcessor是如何自动调用的?

小小白:在Spring容器初始化的过程中会自动触发,具体代码在AbstractApplicationContext类中会调用invokeBeanFactoryPostProcessors方法,在这个方法中筛选出所有实现BeanFactoryPostProcessor接口的类名称,然后遍历调用这些实现类的postProcessBeanFactory方法。

面试官:如果想在bean被初始化时进行拦截,进行额外初始化操作,如何实现?

小小白:自定义BeanPostProcessor,让它实现BeanPostProcessor接口,在这个接口中定义了两个方法:postProcessBeforeInitialization和postProcessAfterInitialization。postProcessBeforeInitialization方法会在afterPropertiesSet和自定义的初始化方法之前执行,通过实现这个方法,在方法的内部进行初始化之前的额外操作。postProcessAfterInitialization方法会在afterPropertiesSet和自定义的初始化方法之后执行,通过实现这个方法,在方法的内部进行初始化之后的额外操作。

面试官:在Spring容器初始化的过程中,所有定义的bean都会被初始化吗?

小小白:不是,默认只初始化所有未初始化的非懒加载的单例Bean,scope为其它值的bean会在使用到的时候进行初始化,如prototype。

面试官:有看过Spring中bean初始化的源码吗?

小小白:看过,单例bean的初始化,通过反射进行实例对象的创建,在进行属性填充时,如果依赖的对象没有创建,则先创建依赖对象,最后将bean实例加入单例bean实例的缓存中。

面试官:在bean实例化的过程中,Spring是如何解决循环依赖的?

小小白:Spring只对单例bean的循环依赖进行了解决,同时如果是通过构造函数注入造成的循环依赖,Spring也没有办法解决,只是抛出BeanCurrentlyInCreationException异常。如果是通过setter方式注入而产生的循环依赖,Spring在创建bean对象时,通过提前暴露一个ObjectFactory用来返回一个创建中的bean对象,从而使其它bean能够引用到这个bean。

面试官:Spring框架中用到了哪些设计模式?

小小白:......额.....


关注[Java实战技术],专注分享Java基础原理分析、实战技术、微服务架构、分布式系统构建。

推荐阅读:

没使用加号拼接字符串,面试官竟然问我为什么

面试官一步一步的套路你,为什么SimpleDateFormat不是线程安全的

都说ThreadLocal被面试官问烂了,可为什么面试官还是喜欢继续问

Java注解是如何玩转的,面试官和我聊了半个多小时

如何去除代码中的多次if而引发的一连串面试问题

三分钟快速搞定git常规使用

synchronized被这么问,谁能受得了

String引发的提问,我差点跪了

就写了一行代码,被狂虐问了这么多问题

面试官:JVM对锁进行了优化,都优化了啥?

超实用高并发编程ExecutorCompletionService案例分析与源码解读

相关推荐

一个基于.Net Core遵循Clean Architecture原则开源架构

今天给大家推荐一个遵循CleanArchitecture原则开源架构。项目简介这是基于Asp.netCore6开发的,遵循CleanArchitecture原则,可以高效、快速地构建基于Ra...

AI写代码翻车无数次,我发现只要提前做好这3步,bug立减80%

写十万行全是bug之后终于找到方法了开发"提示词管理助手"新版本那会儿,我差点被bug整崩溃。刚开始两周,全靠AI改代码架构,结果十万行程序漏洞百出。本来以为AI说没问题就稳了,结果...

OneCode低代码平台的事件驱动设计:架构解析与实践

引言:低代码平台的事件驱动范式在现代软件开发中,事件驱动架构(EDA)已成为构建灵活、松耦合系统的核心范式。OneCode低代码平台通过创新性的注解驱动设计,将事件驱动理念深度融入平台架构,实现了业务...

国内大厂AI插件评测:根据UI图生成Vue前端代码

在IDEA中安装大厂的AI插件,打开ruoyi增强项目:yudao-ui-admin-vue31.CodeBuddy插件登录腾讯的CodeBuddy后,大模型选择deepseek-v3,输入提示语:...

AI+低代码技术揭秘(二):核心架构

本文档介绍了为VTJ低代码平台提供支持的基本架构组件,包括Engine编排层、Provider服务系统、数据模型和代码生成管道。有关UI组件库和widget系统的信息,请参阅UI...

GitDiagram用AI把代码库变成可视化架构图

这是一个名为gitdiagram的开源工具,可将GitHub仓库实时转换为交互式架构图,帮助开发者快速理解代码结构。核心功能一键可视化:替换GitHubURL中的"hub...

30天自制操作系统:第六天:代码架构整理与中断处理

1.拆开bootpack.c文件。根据设计模式将对应的功能封装成独立的文件。2.初始化pic:pic(可编程中断控制器):在设计上,cpu单独只能处理一个中断。而pic是将8个中断信号集合成一个中断...

AI写代码越帮越忙?2025年研究揭露惊人真相

近年来,AI工具如雨后春笋般涌现,许多人开始幻想程序员的未来就是“对着AI说几句话”,就能轻松写出完美的代码。然而,2025年的一项最新研究却颠覆了这一期待,揭示了一个令人意外的结果。研究邀请了16位...

一键理解开源项目:两个自动生成GitHub代码架构图与说明书工具

一、GitDiagram可以一键生成github代码仓库的架构图如果想要可视化github开源项目:https://github.com/luler/reflex_ai_fast,也可以直接把域名替换...

5分钟掌握 c# 网络通讯架构及代码示例

以下是C#网络通讯架构的核心要点及代码示例,按协议类型分类整理:一、TCP协议(可靠连接)1.同步通信//服务器端usingSystem.Net.Sockets;usingTcpListene...

从复杂到优雅:用建造者和责任链重塑代码架构

引用设计模式是软件开发中的重要工具,它为解决常见问题提供了标准化的解决方案,提高了代码的可维护性和可扩展性,提升了开发效率,促进了团队协作,提高了软件质量,并帮助开发者更好地适应需求变化。通过学习和应...

低代码开发当道,我还需要学习LangChain这些框架吗?| IT杂谈

专注LLM深度应用,关注我不迷路前两天有位兄弟问了个问题:当然我很能理解这位朋友的担忧:期望效率最大化,时间用在刀刃上,“不要重新发明轮子”嘛。铺天盖地的AI信息轰炸与概念炒作,很容易让人浮躁与迷茫。...

框架设计并不是简单粗暴地写代码,而是要先弄清逻辑

3.框架设计3.框架设计本节我们要开发一个UI框架,底层以白鹭引擎为例。框架设计的第一步并不是直接撸代码,而是先想清楚设计思想,抽象。一个一个的UI窗口是独立的吗?不是的,...

大佬用 Avalonia 框架开发的 C# 代码 IDE

AvalonStudioAvalonStudio是一个开源的跨平台的开发编辑器(IDE),AvalonStudio的目标是成为一个功能齐全,并且可以让开发者快速使用的IDE,提高开发的生产力。A...

轻量级框架Lagent 仅需20行代码即可构建自己的智能代理

站长之家(ChinaZ.com)8月30日消息:Lagent是一个专注于基于LLM模型的代理开发的轻量级框架。它的设计旨在简化和提高这种模型下代理的开发效率。LLM模型是一种强大的工具,可以...

取消回复欢迎 发表评论: