spring面试必备
2025-09-09 09:57:07 0 举报
AI智能生成
标题:Spring面试必备核心概念精讲 在这篇深入探讨Spring框架的文档中,我们将讲解一些最为关键的核心概念,确保你能够准备周全地面对任何面试挑战。在理解Spring基础的同时,我们也会探索关键的高级特性,包括IoC容器、Spring Bean生命周期管理、AOP(面向切面编程)以及声明式事务管理,让你对Spring有更深入的理解。我们精选的高级概念,如Spring Boot快速启动机制、微服务架构下的Spring Cloud解决方案以及RESTful API设计模式,保证你能够洞悉最新的Spring发展动态。通过此文件,你将有机会巩固基础,同时掌握足以惊艳面试官的高级技能。这份文档包含了丰富的实例代码、图表以及详细的步骤指南,是每个希望精通Spring框架和渴望在面试中脱颖而出的开发者必备的参考资料。
作者其他创作
大纲/内容
Springboot
spring自动配置原理
@Configuration(proxyBeanMethods = false) spring底层会给cglib创建动态代理,,作用是防止每次调用本类的方法都需要重新创建对象
@EnableConfigurationProperties({ServerProperties.class}) Properties文件就是这个配置类可以支持哪些配置
实现Conditional接口
@ConditionalOnWebApplication(type = Type.SERVLET) 实现了Conditional接口,判断是否为webApplication
@ConditionalOnClass({CharacterEncodingFilter.class}) 实现了Conditional接口,判断是否包含CharacterEnvodingFiter.class
@ConditionalOnProperty(
prefix = "server.servlet.encoding",
value = {"enabled"},
matchIfMissing = true
)判断server.servlet.encoding.enabled是否为true
prefix = "server.servlet.encoding",
value = {"enabled"},
matchIfMissing = true
)判断server.servlet.encoding.enabled是否为true
sping自动配置读取原理
@SpringootApplication注解是一个复合注解,它包含了
@SpringBootConfiguration
@EnableAutoConfiguration
用@Import注解引入AutoConfigurationImportSelector类
AutoConfigurationImportSelector继承DeferredImportSelector类
如果实现了了getImportGroup方法,返回了一个继承了DeferredImportSelector.Group的AutoConfigurationGroup类
AutoConfigurationGroup会调用process和selectImports方法
process方法中调用了getAutoConfigurationEntry获取自动配置类的类名,
调用getCandidateConfigurations获取所有autoConfiguration结尾的自动配置类
调用loadFactoryNames
调用loadSpringFactories
该方法中会扫描META-INF/spring.factories文件,并加载文件中的配置类,以map形式加载
该方法中会缓存配置类的信息
selectImports
检查所有传入的配置类,检查注解,排除某些配置类
返回的是一个@Import语句列表,方便后面导入或注册到spring 的容器bean中
如果没有实现getImportGroup方法,会调用AutoConfigurationImportSelector的selectImprots方法
返回一个数组,并注册为Bean
@ComponentScan
是Spring Framwork的注解,用于扫描制定包路径下的所有组件和配置类,并注册为Bean
属性
basePackages:制定需要扫描的路径,在springboot中,如果不指定就扫描的是application的根目录
在AutoConfigurationPackages.Registrar在注册的时候,,使用PackageImport类在构造方法中获取当前配置类的ClassName(),再使用lastIndexOf(".")找到最后一个点,再截取ClassName的字符串,拿到配置类的包路径
basePackageClasses:指定一组component类
includeFilters:包含指定类,使用TypeFilter实现目标类的筛选
excludeFilters:排除指定类,使用TypeFilter实现目标类的筛选
会排除配置类,并且是自动配置的类
springboot启动原理
在springboot项目中,我们的启动类一般放在java目录下面以application.class文件作为启动类
在启动类中需要标注@SpringbootApplication注解,并且在main方法中调用SpringApplication.run(启动类的class对象的引用)静态方法
静态方法中最终依然会实例化SpringApplication,构造参数都是class对象数组,并调用run()方法,
调用的run()方法
记录开始时间
创建一个DefaultBootstrapContext
开启了Headless模式
从spring.factroies读取RunListener组件列表
发布ApplicationStartingEvent事件
实例化一个DefaultApplicationArguments对象
调用prepareEnvironment方法读取配置文件
调用configureIgnoreBeanInfo,
打印横幅,banner
创建ApplicationContext
调用prepareContext方法,该方法在Spring容器上下文准备就绪之前被调用,主要负责一些初始化工作
调用refresh方法,加载自动配置类,初始化ioc容器
发布一个ApplicationStartEvent事件
发布一个AvailabilityChangeEvent事件
发布了ApplicationReadyEvent
Springcloud
微服务演化过程
单体架构
所有功能代码都在一个包里面
垂直架构
沿着不同的业务维度划切成多个垂直的部分,每个部分都可以实现从数据存储,业务逻辑处理到页面展示的完整功能
SOA 面向服务架构
面向服务的架构,是一种软件架构设计理念和方法
服务是SOA架构的核心,它具有独立的功能,且包含可重用的软件单元
微服务架构
可以理解为SOA架构的进一步优化,强调的是“微“,服务的彻底拆分
springData JPA
1.Spring是如何管理repository 的Bean
在注释了@EnableJpaRepositories(basePackages = "com.dgj.repositories")
Bean的本质就是一个对象,接口无法成为Bean
所以在Spring的扫描中会排除接口和抽象类
Spring会将配置的Bean信息注册为BeanDefinition
BeanDefinition中记录了class的信息,通过反射就可以实例化这个Bean
1. 在New ApplicationContext的时候就会创建一个BeanDefinitionReader
BeanDefinitionReader的作用是解析Bean的信息
AnnotatedBeanDefinitionReader
解析的是javaConfig的Bean
XmlBeanDefinitionReader
解析的是xml的Bean
然后扫描器:ClassPathBeanDefinitionScanner,解析 @CompontentScan,通过@CompontentScan设置的basePackages路径进行扫描出所有的Bean
在扫描的过程中会判断是接口或抽象类就不会加载为BeanDefinition
2. Spring是如何将动态代理为Bean
通过FactoryBean实现动态代理Repository
在ClassPathBeanDefinitionScanner
手写repository动态代理
继承ClassPathBeanDefinitionScanner,重写isCandidateComponent方法,将接口也创建BeanDefinition
实现BeanDefinitionRegisterPostProcessor接口,在postProcessBeanDefinitionRegistry中实现自定义扫描类,指定扫描的路径是repository的目录,然后添加接口filter(只有实现了Repository接口的才注册为BeanDefinition),最后加上@Component注解交给IOC管理(这个时如果直接运行会报错,因为自动注入的必须是一个实例化的对象,而现在是一个接口,这个时候需要通过动态代理实例化才能使用)
实现接口动态代理又两种方式一种是在configuration类中添加@Bean注解,但是这个方式一次只能实例化一个repository,如果又多个需要多次实现,效率低,也不符合开发思路
另外一种方式是实现FactoryBean接口,在getObejct的方法中实现动态代理,FactoryBean的是一个特殊的Bean,他可以自定义属性,我们可以通过设置属性的方式动态的传入repository接口,并且通过动态代理实例化然后注册为Bean,
在实现了FactoryBean之后,需要在ClassPathBeanDefinitionScanner的doScan方法中,替换掉BeanDefinition中的BeanClass,这样之后在获取repository的时候就会通过FactoryBean拿到一个实例化的Bean
swagger
swagger2
springfox.swagger2
openapi
springdoc-openapi-ui
SpringFramwork
Bean的生命周期
通过构造方法实例化一个对象
依赖注入(属性设置)
实现Aware 接口的回调,比如:ApplicationContextAware(调用setApplicationContext()方法,传递容器到Bean,可以获取其他Bean或发布事件)
初始化前
初始化(InitializingBean接口,也可以通过@PostConstruct指定初始化方法)
初始化后(AOP)
使用
销毁前
销毁
销毁后
@PostContruct注解
依赖注入之后,但是比BeanPostProcessor之前执行,通常用于数据初始化资源,比如建立数据库链接、加载配置等
BeanPostProcessor接口
可以重写初始化前和初始化后的方法,通常用于统一处理Bean,如果添加日志,性能监控,或对一类Bean统一赋值
IOC容器
AOP
创建ConfigurableEnvironment
读取配置文件
对所有propertis进行排序,将configurationProperties放在第一位
发布ApplicationEnvironmentPreparedEvent事件
将所有spring.main开头的配置信息绑定到SpringApplication类中
再次对propertis进行排序
这里会读取扩展的配置文件
实例化SpringApplication
构造方法
对一些参数赋默认值
检查当前web应用的类型,webApplicationType(REACTIVE或SERVLET)
扫描spring.factories文件
获取BootstrapRegistryInitializer.class的组件
获取ApplicationContextInitializer.class的组件
获取ApplicationListener.class的组件
将环境变量设置到context中
后置处理器处理,获取类型转换器
循环调用ApplicationContextInitializer类的initializer方法
发布ApplicationContextInitializedEvent事件
获取BeanFactory(负责创建Bean,其中有个getBean方法,既是获取bean的方法也是创建Bean的)
注册命令行参数注册为单例Bean
注册横幅为单列Bean
设置是否允许bean的覆盖
设置所有的Bean是否需要懒加载
读取主启动类
发送ApplicationPreparedEvent事件
设计模式
开闭原则
工厂模式
简介
是一种创建型设计,主要用于创建对象的实例,通过将创建和使用分离,避免了直接在代码中使用new,从而提高可维护性和可扩展性
应用
简单工厂模式:BeanFactory
通过读取xml文件或注解将Bean分别存储为BeanDefinition对象,
再通过BeanDefinitionRegistry将Bean注册到BeanFactory中
BeanFactory作为接口提供了IOC容器的具体规范,并不是IOC的具体实现,但是spring提供了多种实现,如:XmlBeanFactory、ApplicationContext等
工厂方法模式:FactoryBean:
FactoryBean是一个特殊的Bean,他允许添加自定义的属性
用户可以通过FactoryBean自定义Bean实例化过程
因为FactroyBean和装饰模式类似,但是FactoryBean主要是提供Bean的实例化逻辑,而不是作为装饰器模式的装饰对象
单列模式
简介
类会控制全局只有一个实例,并提供一个全局访问点访问该实例
应用
Spring中的Bean通常就是单列
Spring中的全局配置也是单列
策略模式
简介
将if else 或switch 的多种策略抽象成一个个对象,但是实际上并没有解决if else 的问题,使用过程中依然需要is else 或switch的支持才能实现不用的策略应用,但是可以结合简单工厂模式将if else或switch隐藏在工厂中,这样在业务逻辑层就会变得简单明了,也更方便扩展和维护
应用
Spring Data中根据不同的数据库选择不同的sql方言
Spring中HttpMessageConverter接口允许使用不同的消息转换器来处理请求
代理模式
简介
是一种结构型设计模式,它允许创建一个代理对象,来控制其他对象的访问,代理对象通常会在客户端和目标对象之间起到中介的作用,可以对目标对象增加额外的功能而不影响目标对象
静态代理
代理类在编译的时候已经知道,需要手动编写代理类
静态代理缺点是如果接口或抽象类发生变化,目标类和代理类都需要相应的实现
动态代理
代理类在运行的时候动态生成,开发者不需要手动编写代理类,java提供了两种动态代理的机制
JDK 动态代理
基于接口的动态代理
CGLIB 动态代理
基于类的动态代理
应用
AOP
事务
缓存机制
安全管理:Spring Secrity
原型模式
简介
原型模式是创建型设计模式,他允许通过复制一个已有对象来创建实例,而不是通过新建,原型模式的关键在"原型",这个对象可以通过克隆自己,来创建新的实例
应用
Spring的依赖注入的时候,如果Bean的作用域设置为propertype,每次获取的时候都会复制一个
适配器模式
简介
子主题
适配器模式是结构型设计模式,他主要作用是将一个类的接口转化为客户端期望的另一种形式,这样就能使不兼容的类一起巩工作
应用
Spring 通过HandlerAdapter将不同的接口适配到DispatcherServlet的格式上
桥接模式
外观模式
简介
外观模式是结构型设计模式,他为子类提供了统一的出口,方便客户端使用,简单来说就是整合多个类的功能与一个类中,客户端只需要使用这个类就能完成所有子类的功能
应用
JDBCtemplate
JDBCTemplate是Spring提供了简化版JDBC操作的类,他封装了很多复杂的功能,如创建连接,创建语句,处理异常等
HibernateTemplate
和JdbcTemplate类似,提供了对外的简单易用的api
DispatcherServlet
享元模式
组合模式
模板方法模式
命令模式
责任链模式
状态模式
观察者模式
简介
观察者模式是一种行为设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生变化的时候,它所以来的所有对象都会收到通知,并且自动更新
应用
Spring在ApplicationContext的生命周期中,内置了多个事件:ContextRefreshedEvent、ContextStartEvent、ContextEndEvent、ContextCloseEvent
事务管理中通过commit事件和rolllback事件实现事务的提交和回滚
中介模式
迭代器模式
访问者模式
备忘录模式
解释器模式
Spring MVC
自动配置提供了哪些功能
ViewResolver视图解析器
比如excel视图解析器
DispatcherServlet
它负责接收http请求,并分发到相应的控制器
静态资源
spring mvc 默认会读取项目资源文件中的/static,/public,/resources,/MAT-INF/resources
HttpMessageConverters
负责http请求的报文处理,比较json转化为对象,
默认的错误处理
比如4**的错误页面
servlet 容器
servlet配置修改
通过配置文件修改
通过实现WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>接口
注册servlet的三大组件
三大组件
servlet
listener
filter
注册方式
servlet3提供注解方式实现
@WebServlet 标记继承了HttpServlet的类是Servlet
在Application类添加@ServletComponentScan,才会扫码 @WebServlet,@WebListener,@Webfilter注解
spring提供registrationBean实现
首先还是需要实现继承了HttpServlet的类
实现一个Bean ->ServletRegistrationBean ,将前面实现的HttpServlet类设置到RegistrationBea中
实现一个源码中的接口
切换其他容器:默认是Tomcat容器
其他容器
Jetty
Undertow
切换方式
排除内嵌的Servlet容器,使用<exclusion>
自动配置原理
通过条件注解自动配置对应的servlet
实现了ServletWebServerFactoryCustomizer实现的WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>接口
通过customzer方法设置sevlet配置
通过@Import引入BeanPostProcessorsRegistrar.class
这个类实现了ImportBeanDefinitionRegistrar接口
registerBeanDefinitions方法中注册了WebServerFactoryCustomizerBeanPostProcessor类
spring会在容器初始化前调用postProcessBeforeInitialization方法,这里将会找出继承了WebServerFactory的类,并调用custormizer
以tomcat为例:
springboot项目run的时候会调用refresh方法
再执行onRefresh方法刷新容器的时候
调用TomcatServletWebServerFactory工厂类的getWebServer
设计思想
控制反转和依赖注入
面相切面编程
AOP
容器化管理
分层架构与组件化
比如controller、service、dao层
配置化与灵活性
可扩展性
对三方技术或插件的整合
自定义扩展点
Java的日志系统
日志门面:不实现日志功能,用来接入其他日志实现
JCL
子主题
slf4j
桥接器:如果要接入某个日志实现,需要用到桥接器
使用log4j的桥接器
slf4j-log4j12
使用lobback的桥接器
logback-classic
使用Jul的桥接器
slf4j-jdk14
适配器
可以将其他日志实现转化到slf4j上面
jcl-over-slf4j
日志实现
log4j
独立开发,后来被apatch收录
性能较低,已经被淘汰
jul
java.util.logging
JDK官方开发的
log4j2
apatch在log4j的基础上开发的,性能更高
logback
log4j的作者开发的,性能更高
多数据源
spring提供了AbstractRoutingDataSource类,我们只需要继承这个类,设置初始数据源,并且实现获取数据源标识的方法就能实现
mybatis提供了一个插件,但是插件只适用于读写分离的应用
在复杂业务中,
0 条评论
下一页