SSM面试题

Spring
IOC
  • 单例bean线程不安全 当多个线程同时对bean修改时 会导致线程不安全 如果bean没有可变状态 如service controller等 则无关紧要

  • bean生命周期

    1. 带有bean标签或注解的类被封装到BeanDefinition中

    2. BeanDefinition调用要创建的类的构造函数

    3. 对bean需要的依赖进行注入 由Spring进行

    4. 实现Aware接口

    5. 执行前置处理器

    6. 执行初始化方法

    7. 执行后置处理器

    8. 销毁

  • bean循环引用 当两个或多个bean中的依赖互相引用 此时多个bean均未创建 彼此需要互相引用 就构成死循环 均无法成功创建

    Spring的三级缓存可以解决这个问题 spring三级缓存分别存放单例池 初始化完成bean(一级) 未完成初始化bean(二级) bean的工厂(三级)当A需要B注入时 若此时B还未创建成功 存在于二级缓存中 Spring就会从缓存中取出尚未完成的bean注入到A中 完成A的创建 另外 如果B仅支持单例 则无法成功 此时需要从三级缓存中拿到B对应的工厂 建立一个新bean并存储到二级缓存中 再次尝试从二级缓存中取出就可以成功创建A

  • 构造方法重复依赖 我们可以添加一个@Lazy注解 当B被使用时 才注入B

AOP

将多个方法共同且与业务无关的部分提取出来 降低代码耦合性

例如用于日志记录 运用环绕通知和切点 取得切点的方法名 参数等信息 保存到数据库中

事务

事务的原理是运用aop在方法执行之前开启事务 在方法结束之后提交事务 若中间有异常抛出 则自动回滚

事务失效

  1. 当方法内处理了异常但没有将其抛出 aop识别不到异常 但内部方法只进行一半 就会出现事务失效的情况 解决方法是在处理异常后再抛出一个新的运行时异常

  2. 当方法内抛出检查性异常 aop默认只识别非检查性异常 当抛出异常后 事务不会回滚 导致事务失效 解决方法是在@Transactional设置rollbackfor的值为Exception.class

  3. 当方法不为public方法时 事务失效 aop是基于动态代理来完成的 动态代理只能代理public方法

SpringMVC
执行流程

前端执行器DispatcherServlet获取前端的请求 再根据请求的路径去HandlerMapping中找到对应的处理器以及拦截器 然后将得到的结果返回给前端执行器 再调用HandlerAdapter来执行对应controller等 若采用的是前后端分离的架构 则会运用HttpMessageConverter来返回得到的json串

SpringBoot
自动配置原理

SpringBootApplication注解封装了EnableAutoConfiguration注解 它通过Import注解导入配置选择器 选择器读取META-INF/spring.factories的配置类 在配置类中定义的bean会根据注解设置的条件是否成立 来判断是否将其加入Spring容器中

例如ConditionOnClass就是需要判断是否存在对应的Class文件 如果存在 才将这个bean加入容器中

Mybatis
执行流程
  1. 读取配置文件或配置类

  2. 创建SqlSessionFactory

  3. 创建SqlSession

  4. 调用数据库接口 Executor执行器

  5. 执行器执行方法中的MapperStatement参数

  6. MapperStatement将输入参数转化为数据库能识别的格式

  7. MapperStatement将输出参数转化为java能识别的格式

延迟加载

支持延迟加载 在配置文件中开启lazyLoadingEnabled或者在配置类中使用注解来开启

多级缓存

Mybatis分为一、二级缓存

一级缓存是作用域为session 只有同一个session才能读取到缓存中内容 当一个session读取数据库数据后 会使用PerpetualCache将数据存入HashMapper中 当session关闭或者刷新后 一级缓存内容会转移到二级缓存中 并清空一级缓存

二级缓存依赖于mapper 同一个mapper的不同sqlsession均可以读取到缓存中的内容 数据结构与一级缓存相同 但数据需要实现Seriailzable接口 当一级缓存或二级缓存中出现新增 删除 修改操作后 二级缓存的查询数据将被清空

你可能感兴趣的:(spring,java,mybatis)