面试八股文专题----SSM框架篇

简介: 本篇深入解析SSM框架核心:Spring的IOC/DI、AOP、事务管理及传播行为,详解JDK/CGLIB代理差异;SpringMVC请求流程与常用注解;Mybatis动态SQL、多表查询、缓存机制及批量操作,全面掌握企业级开发关键技术要点。

2-SSM框架篇

01-什么是Spring IOC 和DI ?

IOC(控制反转):把传统上由程序代码直接操控的对象调用权交给容器,通过容器实现对象组件的装配和管理。“控制反转”的核心是组件对象控制权的转移,从程序代码本身转移到外部容器,不再由开发者手动创建和管理对象,而是由Spring容器统一管控。
DI(依赖注入):是IOC的具体实现方式,在创建对象的过程中,将对象所依赖的属性(比如其他类的实例)自动注入到该类中,无需开发者手动设置依赖,以此实现对象间依赖关系的解耦。

02-有哪些不同类型的依赖注入实现方式?

依赖注入主要有三种实现方式:

  1. 接口注入:通过特定接口暴露依赖注入的入口,容器借助该接口将依赖注入到目标对象中(实际开发中极少使用);
  2. 构造器依赖注入:容器通过触发类的构造器完成注入,该类的构造器包含一系列参数,每个参数对应对其他类的依赖,容器会在创建对象时传入这些依赖对象;
  3. Setter方法注入:容器先通过无参构造器或无参static工厂方法实例化Bean,再调用该Bean的Setter方法,将依赖对象注入,是实际开发中最常用的注入方式。

03- Spring支持的几种bean的作用域 Scope

Spring框架支持五种Bean作用域:

  1. singleton(单例):每个Spring IOC容器中,该Bean仅存在一个实例,是Spring Bean的默认作用域;
  2. prototype(原型):一个Bean定义可以创建多个实例,每次从容器中获取该Bean时都会生成新的实例;
  3. request(请求):每次HTTP请求都会创建一个新的Bean实例,该作用域仅在基于Web的Spring ApplicationContext环境下有效;
  4. session(会话):在一个HTTP Session生命周期内,一个Bean定义对应一个实例,仅在基于Web的Spring ApplicationContext环境下有效;
  5. global-session(全局会话):在全局HTTP Session中,一个Bean定义对应一个实例,主要用于Portlet环境,仅在基于Web的Spring ApplicationContext环境下有效。

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

Spring框架中的单例Bean本身不是线程安全的。因为Spring默认的Bean是单例模式,Spring框架并未对单例Bean做多线程相关的封装或同步处理。
但实际开发中,若单例Bean中不包含共享的成员变量(比如全局的状态数据),仅作为无状态的工具类/服务类使用,就不会出现线程安全问题;从这个角度来说,日常使用的单例Bean通常是“线程安全”的。

05- spring 自动装配 bean 有哪些方式?

在Spring框架的XML配置中,主要有3种核心自动装配方式:

  1. byName(按名称装配):根据Bean的名称进行自动装配,如果一个Bean的属性名与另一个Bean的name属性值相同,Spring容器会自动将后者注入到前者的该属性中;
  2. byType(按类型装配):根据参数的数据类型进行自动装配,如果容器中存在唯一匹配该属性类型的Bean,就将其注入;若存在多个同类型Bean,会抛出异常;
  3. constructor(构造器装配):利用构造函数完成装配,构造函数的参数会通过byType方式匹配容器中的Bean,再注入到构造器中创建对象。

06- Spring中的事务是如何实现的

Spring事务底层基于数据库事务和AOP(面向切面编程)机制实现,核心流程如下:

  1. 对于标注了@Transactional注解的Bean,Spring会为其创建代理对象;
  2. 调用代理对象的方法时,先判断方法上是否有@Transactional注解;
  3. 若有注解,通过事务管理器创建数据库连接,并将该连接的autocommit(自动提交)属性设为false(这是Spring事务实现的关键步骤);
  4. 执行当前方法中的SQL逻辑;
  5. 方法执行完成后,若无异常则提交事务;若出现异常,且该异常属于需要回滚的类型(默认是RuntimeException及其子类),则回滚事务,否则仍提交事务;
  6. Spring事务的隔离级别直接对应数据库的隔离级别;事务的传播机制是Spring自身实现的核心特性,基于数据库连接实现:一个数据库连接对应一个事务,若传播机制要求新开事务,本质是新建一个数据库连接并在该连接上执行SQL。

07- Spring中事务失效的场景

Spring事务基于动态代理实现,以下场景会导致@Transactional注解失效:

  1. 非代理对象调用:加了@Transactional的方法被Bean自身(而非代理对象)调用(比如内部方法调用),注解无法被Spring的AOP拦截,导致失效;
  2. 方法为private修饰:底层CGLIB动态代理基于父子类实现,子类无法重载父类的private方法,代理无法生效,@Transactional失效;
  3. 异常被手动捕获:业务代码中捕获了异常且未重新抛出,Spring框架无法感知异常,无法触发事务回滚,导致事务失效;
  4. 注解标注在非public方法上:Spring AOP仅对public方法的@Transactional做代理处理,非public方法注解无效。

08- 说一下Spring的事务传播行为

Spring事务传播行为定义了多个带有事务的方法相互调用时,事务的创建、加入或挂起规则,核心传播行为如下:

  1. PROPAGATION_REQUIRED(默认):如果当前无事务,创建新事务;如果当前已有事务,加入该事务,是最常用的设置;
  2. PROPAGATION_SUPPORTS:支持当前事务,若当前有事务则加入,若无则以非事务方式执行;
  3. PROPAGATION_MANDATORY:强制要求当前存在事务,若有则加入,若无则抛出异常;
  4. PROPAGATION_REQUIRES_NEW:无论当前是否有事务,都创建新事务(原有事务会被挂起,新事务执行完后恢复原有事务);
  5. PROPAGATION_NOT_SUPPORTED:以非事务方式执行,若当前有事务则将其挂起;
  6. PROPAGATION_NEVER:以非事务方式执行,若当前存在事务则抛出异常;
  7. PROPAGATION_NESTED:若当前有事务,在嵌套事务内执行(嵌套事务依赖外层事务,外层回滚则嵌套也回滚,嵌套回滚不影响外层);若当前无事务,按PROPAGATION_REQUIRED规则执行。

09- JDK动态代理和CGLIB动态代理的区别

Spring AOP的动态代理主要有JDK动态代理和CGLIB动态代理两种方式,核心区别如下:

  1. 实现原理:JDK动态代理基于接口实现,通过Proxy.newProxyInstance(类加载器, 代理对象实现的所有接口, 代理执行器)创建代理对象,仅支持对接口的代理;CGLIB动态代理基于继承实现,通过Enhancer.create(父类的字节码对象, 代理执行器)创建代理对象,代理类是目标类的子类;
  2. 适用范围:JDK动态代理要求目标类必须实现接口,否则无法代理;CGLIB无需目标类实现接口,但目标类若被标记为final(无法被继承),则无法使用CGLIB代理;
  3. 性能:JDK1.8后JDK动态代理性能优于CGLIB,低版本JDK中CGLIB性能更优。

10- 什么是AOP , 你们项目中有没有使用到AOP

AOP(面向切面编程):作为面向对象编程(OOP)的补充,将与业务无关但对多个对象产生影响的公共行为和逻辑(比如日志、权限、事务)抽取封装为可重用的“切面(Aspect)”,减少系统重复代码,降低模块耦合度,提升可维护性。
项目中直接手写AOP的场景较少,但大量框架功能底层基于AOP实现:比如Spring的事务管理(@Transactional)、权限认证(比如拦截请求校验权限)、系统日志记录(统一记录接口入参出参)、异常统一处理等,都是AOP的典型应用。

11- SpringMVC的执行流程知道嘛

SpringMVC的核心执行流程如下:

  1. 用户发送HTTP请求至前端控制器DispatcherServlet;
  2. DispatcherServlet调用HandlerMapping(处理器映射器),根据请求URL查找对应的Handler(处理器,即Controller中的方法);
  3. HandlerMapping返回处理器对象及对应的处理器拦截器(若有)给DispatcherServlet;
  4. DispatcherServlet调用HandlerAdapter(处理器适配器),适配并执行对应的Handler;
  5. HandlerAdapter适配后调用具体的Handler(后端控制器),Handler执行完成后返回ModelAndView(模型数据+视图名称);
  6. HandlerAdapter将ModelAndView返回给DispatcherServlet;
  7. DispatcherServlet将ModelAndView传给ViewResolver(视图解析器),视图解析器解析出具体的View(视图);
  8. DispatcherServlet对View进行渲染(将Model中的数据填充到视图中);
  9. DispatcherServlet将渲染后的视图响应给用户。

12- Spring MVC常用的注解有哪些?

Spring MVC常用注解及作用:

  1. @RequestMapping:处理请求URL映射,可标注在类或方法上;标注在类上时,类中所有响应请求的方法都以该地址为父路径;
  2. @RequestBody:接收HTTP请求中的JSON数据,自动将JSON转换为Java对象;
  3. @ResponseBody:将Controller方法的返回对象转换为JSON对象,响应给客户端;
  4. @Controller:标注类为Spring MVC的控制器(表现层),是核心注解,无法被其他注解替代;
  5. @RestController:组合注解,等价于@Controller + @ResponseBody,标注后方法返回值直接以JSON响应,无需额外加@ResponseBody;
  6. @GetMapping/@PostMapping/@PutMapping/@DeleteMapping:分别对应GET/POST/PUT/DELETE请求的映射注解,是@RequestMapping的简化版;
  7. @PathVariable:接收请求路径中的路径变量(比如/{id}中的id);
  8. @RequestParam:接收请求参数(比如URL中的?id=123或表单参数),可指定参数名、是否必传、默认值等。

13- Mybatis #{}和${}的区别

Mybatis中#{}和${}是两种参数绑定方式,核心区别如下:

  1. 处理方式:#{}是占位符,做预编译处理;Mybatis会将SQL中的#{}替换为?,调用PreparedStatement的set方法赋值,参数以字符串形式传入;${}是字符串拼接符,做字符串替换,无预编译处理,直接将参数拼接到SQL中;
  2. 安全性:#{}能有效防止SQL注入(因为预编译处理,参数被当作值而非SQL语句),提升系统安全性;${}无法防止SQL注入,参数直接拼接可能被恶意注入;
  3. 替换位置:#{}的变量替换在数据库系统内部完成;${}的变量替换在数据库系统外(Mybatis框架层面)完成。

14- Mybatis 如何获取生成的主键

Mybatis获取插入操作生成的主键主要有两种方式:

  1. 基于insert标签属性:在insert标签上添加useGeneratedKeys="true"(开启获取自增主键),同时设置keyProperty="主键字段名"(比如userId),插入后主键值会自动填充到实体类的对应属性中;
  2. 基于selectKey标签:在insert标签内部添加selectKey标签,通过执行SQL(比如MySQL的select last_insert_id())查询生成的主键,并将结果赋值给实体类的主键属性。

15- 当实体类中的属性名和表中的字段名不一样 ,怎么办

解决实体类属性名与数据库表字段名不一致的问题,主要有两种方式:

  1. SQL别名方式:在查询SQL中为字段名定义别名,使别名与实体类的属性名一致(比如SELECT user_name AS userName FROM user);
  2. ResultMap映射方式:在Mybatis的映射文件中定义ResultMap,明确指定数据库字段名与实体类属性名的映射关系,是更通用、可复用的方式。

16- Mybatis如何实现多表查询

Mybatis实现多表查询主要有两种方式:

  1. 关联查询方式:编写多表关联的SQL语句(比如JOIN),通过ResultMap建立结果集映射,使用association标签(一对一关联)、collection标签(一对多关联)映射关联对象/集合;
  2. 分步查询方式:将多表查询拆分为多个单表查询,在ResultMap的association/collection标签中通过select属性指定另一个SQL的ID,Mybatis会自动执行该SQL并将结果封装到关联对象/集合中。

17-Mybatis都有哪些动态sql?能简述一下动态sql的执行原理吗?

Mybatis动态SQL允许在XML映射文件中通过标签编写动态逻辑,完成SQL的条件拼接,核心动态SQL标签包括:trim、where、set、foreach、if、choose、when、otherwise、bind共9种。
动态SQL的执行原理:Mybatis通过OGNL(对象图导航语言)从SQL参数对象中计算表达式的值,根据表达式的结果动态拼接SQL语句,最终生成可执行的SQL并执行,以此实现SQL的动态调整。

18- Mybatis是否支持延迟加载?

Mybatis支持延迟加载(懒加载),但仅支持association(一对一关联)和collection(一对多关联)对象的延迟加载:

  1. 延迟加载的核心逻辑:查询主表数据时,不立即查询关联表数据,仅在首次访问关联对象/集合时,才执行关联查询;
  2. 开启方式:在Mybatis的核心配置文件中设置lazyLoadingEnabled=true(默认false),即可启用全局延迟加载;也可在ResultMap的association/collection标签中单独配置延迟加载规则。

19- 如何使用Mybatis实现批量插入 ?

Mybatis通过foreach标签实现批量插入,foreach标签可迭代集合并拼接SQL,核心步骤如下:

  1. 在insert标签中使用foreach标签遍历需要插入的集合;
  2. foreach标签的核心属性:
    • collection:指定要遍历的集合参数名(比如list、array);
    • item:迭代集合时,每个元素的别名(自定义变量名);
    • index:迭代过程中当前元素的索引(不常用);
    • open:指定拼接SQL的起始字符(比如"(");
    • separator:指定迭代元素之间的分隔符(比如",");
    • close:指定拼接SQL的结束字符(比如")");
  3. 拼接INSERT INTO ... VALUES (...)的批量插入SQL,完成批量插入。

20- Mybatis 批量插入是否能够返回主键

Mybatis批量插入可以返回生成的主键,主键值会自动封装到传入的集合中每个对象的主键属性里:例如批量插入List,插入后每个User对象的id(主键)属性会被赋值为数据库生成的自增主键。

21- Mybatis的一级、二级缓存 ?

Mybatis的缓存分为一级缓存和二级缓存,核心内容如下:

  1. 一级缓存:基于SqlSession级别的缓存,默认开启。同一个SqlSession中,多次执行相同的SQL查询,会将结果缓存到一级缓存中,后续查询直接从缓存获取,无需访问数据库;关闭SqlSession后,一级缓存失效;
  2. 二级缓存:基于SqlSessionFactory的NameSpace(命名空间)级别缓存,默认未开启,需手动配置:
    • 第一步:在Mybatis核心配置文件中开启全局二级缓存:;
    • 第二步:在Mapper映射文件中配置cache标签:(eviction为缓存淘汰策略,flushInterval为刷新间隔,size为缓存最大条目数);
      二级缓存跨SqlSession生效,同一个NameSpace下的多个SqlSession可共享缓存,提升查询效率。

总结

  1. SSM核心:Spring的IOC/DI实现对象解耦,事务基于AOP+数据库连接实现,需注意代理、异常捕获等导致的事务失效场景;
  2. SpringMVC核心是DispatcherServlet为中心的请求分发流程,常用注解简化请求映射和参数/响应处理;
  3. Mybatis核心是参数绑定(#{}防注入)、动态SQL、多表查询(association/collection)、缓存(一级默认开启,二级手动配置),批量操作依赖foreach标签实现。
相关文章
|
13天前
|
数据采集 人工智能 安全
|
8天前
|
编解码 人工智能 自然语言处理
⚽阿里云百炼通义万相 2.6 视频生成玩法手册
通义万相Wan 2.6是全球首个支持角色扮演的AI视频生成模型,可基于参考视频形象与音色生成多角色合拍、多镜头叙事的15秒长视频,实现声画同步、智能分镜,适用于影视创作、营销展示等场景。
663 4
|
8天前
|
机器学习/深度学习 人工智能 前端开发
构建AI智能体:七十、小树成林,聚沙成塔:随机森林与大模型的协同进化
随机森林是一种基于决策树的集成学习算法,通过构建多棵决策树并结合它们的预测结果来提高准确性和稳定性。其核心思想包括两个随机性:Bootstrap采样(每棵树使用不同的训练子集)和特征随机选择(每棵树分裂时只考虑部分特征)。这种方法能有效处理大规模高维数据,避免过拟合,并评估特征重要性。随机森林的超参数如树的数量、最大深度等可通过网格搜索优化。该算法兼具强大预测能力和工程化优势,是机器学习中的常用基础模型。
350 164
|
7天前
|
机器学习/深度学习 自然语言处理 机器人
阿里云百炼大模型赋能|打造企业级电话智能体与智能呼叫中心完整方案
畅信达基于阿里云百炼大模型推出MVB2000V5智能呼叫中心方案,融合LLM与MRCP+WebSocket技术,实现语音识别率超95%、低延迟交互。通过电话智能体与座席助手协同,自动化处理80%咨询,降本增效显著,适配金融、电商、医疗等多行业场景。
359 155