这里根据个人说话口吻等编写Spring常见面试题用于记录复习,后续会持续更新补充,欢迎点赞收藏。
开发框架
Spring
spring包含哪些模块
4.x版本

5.x版本

spring,spring mvc,spring boot的关系是什么
spring是包含了多个功能模块的轻量级java开发框架。而spring mvc是spring的一个重要模块,主要赋予spring快速构建mvc架构的web程序的能力。springboot则是基于spring的再封装简化,做到开箱即用。
说说spring的核心思想
1.ioc,解耦了对象的创建与依赖管理,通过容器管理bean的生命周期实现控制反转
2.di,依赖注入,解决了依赖关系的硬编码
3.aop,面向切面编程,能够解决横切逻辑分散在业务代码之中
介绍Spring IOC
1.ioc即为控制反转,是一种创建和获取对象的技术思想,通过ioc
容器来管理对象的依赖关系
2.IOC容器利用Java反射机制动态加载类,创建实例调用方法等。IOC的核心概念是依赖注入,通过容器管理应用程序组件的依赖关系。
3.IOC容器常用工厂模式管理对象的创建和生命周期。
介绍AOP
1.面向切面编程,能够将那些与业务无关的分散在业务代码中的横切逻辑统一管理封装,减少系统的重复代码,降低模块耦合。
2.AOP的实现依赖动态代理技术,在运行时生成代理对象。支持jdk与cglib的动态代理。
3.在我的协同编辑图库项目中最初阶段通过AOP实现了鉴权模块。
介绍DI
1.相比传统new关键字创建依赖对象,DI(依赖注入)将对象创建和依赖关系交给spring容器管理,类只需要声明需要依赖的对象,容器就会在运行时将这些对象注入到类中
2.常见的di注入有三种,构造器注入,setter注入,注解注入
如果让你设计一个SpringIoc,你觉得会从哪些方面考虑这个设计?/spring ioc的功能
1.Bean生命周期管理与bean的创建:使用工厂/单例模式实现
2.Bean的作用域管理:可以考虑Map存储不同作用域的bean
3.依赖注入实现:构造器注入,setter注入,注解注入。使用反射机制,xml配置文件实现
4.AOP功能支持:使用动态代理机制,切面编程实现
5.异常处理:使用try-catch机制处理异常
Bean的生命周期
bean的实例化
-
通过
BeanDefinition获取bean的定义信息。 -
通过反射机制实例化bean。
bean的属性赋值
- 进行bean的依赖注入,例如通过setter方法或
@Autowired注解。
bean感知容器
- 处理实现了
Aware接口的bean。
bean的初始化
-
执行
BeanPostProcessor的前置处理器。 -
调用初始化方法,如实现了
InitializingBean接口或自定义的init-method。 -
执行
BeanPostProcessor的后置处理器,可能在这里产生代理对象。
bean的使用
bean的销毁
-
如果 Bean 实现了
DisposableBean接口,执行destroy()方法 -
如果 Bean 在配置文件中的定义包含
destroy-method属性,执行指定的方法
「造壳→填值→知环境→就绪→清理」

spring如何解决循环依赖问题
1.循环依赖是指两个或两个以上的bean相互持有对方,形成依赖闭环。
2.spring使用三级缓存解决大部分循环依赖问题。一级缓存是个单例池,缓存已经完成初始化的bean对象。二级缓存用来缓存尚未完成初始化的早期bean对象。三级缓存用来缓存objectfactory,用来创建bean对象。
循环引用具体解决流程
-
实例化A对象,并创建
ObjectFactory存入三级缓存。 -
A在初始化时需要B对象,开始B的创建逻辑。
-
B实例化完成,也创建
ObjectFactory存入三级缓存。 -
B需要注入A,通过三级缓存获取
ObjectFactory生成A对象,存入二级缓存。 -
B通过二级缓存获得A对象后,B创建成功,存入一级缓存。
-
A对象初始化时,由于B已创建完成,可以直接注入B,A创建成功存入一级缓存。
-
清除二级缓存中的临时对象A。
为什么是三级缓存,二级缓存行不行
1.三级缓存可以处理被代理的bean,二级缓存不行。
2.在A和B循环依赖,且A被动态代理的场景下。如果使用二级缓存,B依赖A,只能注入A的原始对象,但容器最终会生成代理对象A。此时会出现两个不同实例,违背单例约束。
3.使用三级缓存可通过objectfactory提前生成代理对象放入二级缓存中解决该问题
构造方法出现了循环依赖怎么解决?
由于构造函数是bean生命周期中最先执行的,Spring框架无法解决构造方法的循环依赖问题。可以使用@Lazy懒加载注解,延迟bean的创建直到实际需要时。
spring框架用到了哪些设计模式
1.单例模式:spring的bean默认单例
2.工厂模式:spring使用工厂模式baenfactory,application context创建bean
3.代理模式:AOP的实现,底层依赖动态代理
4.模板方法模式:spring中的jdbctemplate等以template结尾对数据库操作的均使用了模板模式
5.适配器模式:AOP的增强或通知,一级mvc中的controller都使用了适配器模式。
Spring的常见注解
注入bean有@autowired,@resource,@qualifier
声明bean有@component,@service,@controller,@repository
设置作用域有@scope
配置相关有@configuration,@compoentscan,@bean
aop相关注解@aspect,@before,@after,@around,@pointcut
@Component与@Bean的区别
1.@Component作用于类,@Bean作用于方法
2.@Bean的自定义性更高,当我们需要把第三方类装配到spring容器时只能通过@Bean实现。
3.@Component配合@ComponentScan通过类路径扫描类并存入容器。@Bean是在spring启动被标注的方法时,将方法返回对象存入容器
@Resource与Autowired的区别
1.@Autowired默认使用byType注入,当一个接口存在多个实现类,会采用byName。可以通过@qualifiler指定名称
2.@Resource默认使用byName注入,当无法匹配时会采用byType。
事务在哪些情况下会失效
事务失效的核心是aop代理未生效或者事务上下文未被正确识别
1.事务方法被本类内部调用。黑马点评出现该情况,通过代理对象解决。
2.事务访问权限不是public,aop只拦截public方法
3.异常被捕获但未被抛出,事务默认只在捕获未被处理的runtime exception时回滚
4.抛出异常类型不匹配,可在rollbackfor中配置
5.事务传播属性设置不当
怎么使用事务
1.编程式:TransactionTemplate或者TransactionManager,在协同编辑图库项目中使用,由于降低事务粒度
2.注解式:@Transactional
springbean的单例
1.spring bean默认单例,但也可以把scope属性改为prototype实现多例
2.如果spring的单例bean具有多种状态,那将可能面临线程安全问题。
3.单例bean的生命周期交给ioc容器管理,而prototype的bean创建后交给使用者使用
springbean的作用域
bean的作用域(scope)定义了bean的生命周期和可见范围。主要有以下几种
1.singleton单例
2.prototyep原型
3.request请求
4.session会话
5.application
6.wrbsocket
Spring boot
什么是约定大于配置
通过预设好的默认规则,帮助开发者大大减少需要手动配置的步骤,从而提升开发效率。主要体现在以下几个方面
1.自动化配置,比如在引入spring-boot-starter-web后spring boot会自动配置tomcat和spring mvc。
2.默认配置,springboot提供了大量默认配置,如连接数据库,设置web服务器等等
3.约定好的项目结构,例如主应用程序类放在根包下
springboot自动配置原理
1.springboot的自动配置基于@springbootapplication注解,它封装了@springbootconfiguration,@enableautoconfiguration和@componentscan
2.@componentscan由于配置组件扫描规则,springbootconfiguration表明当前类是springboot的配置类
3.enableautoconfiguration是自动配置的核心,它通过@Import导入配置选择器,读取META-INF/spring.factories文件中的类名,根据条件注解决定是否将配置类中的bean导入spring容器中
springboot常见注解
-
@SpringBootApplication:用于标注主应用程序类,标识一个Spring Boot应用程序的入口点,同时启用自动配置和组件扫描。
-
@RestController:结合@Controller和@ResponseBody,返回RESTful风格的数据。
-
@Value:用于注入配置属性值。
-
@RequestMapping:用于映射HTTP请求路径到Controller的处理方法。
-
@GetMapping、@PostMapping、@PutMapping、@DeleteMapping:简化@RequestMapping的GET、POST、PUT和DELETE请求。
- @Configuration:用于指定一个类为配置类,其中定义的bean会被Spring容器管理。通常与@Bean配合使用,@Bean用于声明一个Bean实例,由Spring容器进行管理。
Spring MVC
SpringMVC的执行流程
1.浏览器发来请求,DispatcherServlet拦截请求
2.DispatcherServlet根据请求调用HandlerMapping。HandlerMapping根据请求url找到具体处理器,并将处理器与拦截器返回给DispatcherServlet
3.DispatcherServlet调用HandlerAdapter。HandlerAdapter适配并调用具体Controller执行,并返回ModelAndView
4.DispatcherServlet调用ViewResolver进行视图解析,如何再渲染视图并响应给用户
拦截器与过滤器
1.过滤器Filter是Servlet规范一部分,在到达Servlet之前执行。过滤器对所有类型的请求过滤,包括静态资源请求。
2.拦截器Inteceptor是MVC框架提供的机制,在请求到达Servlet之后执行。拦截器只能对mvc控制器的请求拦截。
Mybatis
Mybatis里的 # 和 $ 的区别?
1.使用#{}会创建预编译sql语句,将#{}替换为?。并且提供preparedstatement赋值,可自动类型转换,防止sql注入
2.使用${}只是创建普通的sql语句,将参数拼接到sql中,可能存在sql注入的问题。
MyBatis执行流程
MyBatis的执行流程如下:
-
读取MyBatis配置文件
mybatis-config.xml。 -
构造会话工厂
SqlSessionFactory。 -
会话工厂创建
SqlSession对象。 -
操作数据库的接口,
Executor执行器。 -
Executor执行方法中的MappedStatement参数。 -
输入参数映射。
-
输出结果映射。
Mybatis的延迟加载
1.可以在配置文件中的lazyLoadingEnabled配置
2.懒加载的底层使用cglib动态代理实现。
Mybatis的一级、二级缓存是什么?
MyBatis的一级缓存是基于Perpetual``Cache的HashMap本地缓存,作用域为Session,默认开启。二级缓存需要单独开启,作用域为Namespace或mapper,默认也是采用PerpetualCache,HashMap存储。
