SpringBoot常见注解
工厂模式 : Spring 容器本质是一个大工厂,使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。
代理模式 : Spring AOP 功能功能就是通过代理模式来实现的,分为动态代理和静态代理。
单例模式 : Spring 中的 Bean 默认都是单例的,这样有利于容器对 Bean 的管理。
模板模式 : Spring 中 JdbcTemplate、RestTemplate 等以 Template 结尾的对数据库、网络等等进行操作的模板类,就使用到了模板模式。
观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
适配器模式 :Spring AOP 的增强或通知 (Advice) 使用到了适配器模式、Spring MVC 中也是用到了适配器模式适配 Controller。
策略模式:Spring 中有一个 Resource 接口,它的不同实现类,会根据不同的策略去访问资源。
你知道 Spring 容器启动阶段会干什么吗?
Spring框架中单例bean是线程安全的吗?
不是线程安全的
Spring框架中 有一个@Scope
的注解,他默认是singleton,他是单例的
然后一般我们Spring的bean 都是无状态注入的。没有线程安全问题, 但是有一些可以修改的成员变量是要考虑线程安全的,可以用多例或者加锁来解决
在类中定义一个 ThreadLocal 成员变量,将需要的可变成员变量保存在 ThreadLocal 中(推荐的一种方式)。
@Autowired 和 @Resource 的区别是什么?
@Autowired 是 Spring 提供的注解,@Resource 是 JDK 提供的注解。
Autowired 默认的注入方式为byType(根据类型进行匹配),@Resource默认注入方式为 byName(根据名称进行匹配)。
当一个接口存在多个实现类的情况下,@Autowired 和@Resource都需要通过名称才能正确匹配到对应的 Bean。Autowired 可以通过 @Qualifier 注解来显式指定名称,@Resource可以通过 name 属性来显式指定名称。
@Autowired 支持在构造函数、方法、字段和参数上使用。@Resource 主要用于字段和方法上的注入,不支持在构造函数或参数上使用。
Bean的作用域
spring 中 Bean 的作用域通常有下面几种:
singleton : IoC 容器中只有唯一的 bean 实例。Spring 中的 bean 默认都是单例的,是对单例设计模式的应用。
prototype : 每次获取都会创建一个新的 bean 实例。也就是说,连续 getBean() 两次,得到的是不同的 Bean 实例。
request (仅 Web 应用可用): 每一次 HTTP 请求都会产生一个新的 bean(请求 bean),该 bean 仅在当前 HTTP request 内有效。
session (仅 Web 应用可用) : 每一次来自新 session 的 HTTP 请求都会产生一个新的 bean(会话 bean),该 bean 仅在当前 HTTP session 内有效。
application/global-session (仅 Web 应用可用):每个 Web 应用在启动时创建一个 Bean(应用 Bean),该 bean 仅在当前应用启动时间内有效。
websocket (仅 Web 应用可用):每一次 WebSocket 会话产生一个新的 bean。
什么是AOP,使用过吗
AOP简单来说就是切面编程 让项目重复的代码减少,降低我们的耦合度 提高可维护性
使用场景:
记录操作的日志
缓存处理
Spring中内置的事务处理
面试官:你们项目中有没有使用到AOP
候选人:
我们当时在后台管理系统中,就是使用aop来记录了系统的操作日志
主要思路是这样的,使用aop中的环绕通知+切点表达式,这个表达式就是要找到要记录日志的方法,然后通过环绕通知的参数获取请求方法的参数,比如类信息、方法信息、注解、请求方式等,获取到这些参数以后,保存到数据库
Spring中的事务是如何实现的?
Spring的事务传播机制有哪些?
REQUIRED,如果不存在事务则开启一个事务,如果存在事务则加入之前的事务,总是只有一个事务在执行
●REQUIRES_NEW,每次执行新开一个事务
●SUPPORTS,有事务则加入事务,没有事务则普通执行
●NOT_SUPPORTED,有事务则暂停该事务,没有则普通执行
●MANDATORY,强制有事务,没有事务则报异常
●NEVER,有事务则报异常
●NESTED,如果之前有事务,则创建嵌套事务,嵌套事务回滚不影响父事务,反之父事务影响嵌套事务
Spring事务失效的场景
异常捕获处理
抛出检查异常
非public方法
面试官:Spring中事务失效的场景有哪些
候选人:
嗯!这个在项目中之前遇到过,我想想啊
第一个,如果方法上异常捕获处理,自己处理了异常,没有抛出,就会导致事务失效,所以一般处理了异常以后,别忘了跑出去就行了
第二个,如果方法抛出检查异常,如果报错也会导致事务失效,最后在spring事务的注解上,就是@Transactional上配置rollbackFor属性为Exception,这样别管是什么异常,都会回滚事务
第三,我之前还遇到过一个,如果方法上不是public修饰的,也会导致事务失效
嗯,就能想起来那么多
Spring的bean的生命周期
通过bean的配置文件找到bean信息
通过构造函数构建bean
注入依赖
实现aware接口
前置处理器
初始化方法
后置处理器
销毁
Spring中的循环引用
①一级缓存:单例池,缓存已经经历了完整的生命周期,已经初始化完成的bean对象
②二级缓存:缓存早期的bean对象(生命周期还没走完)
③三级缓存:缓存的是ObjectFactory,表示对象工厂,用来创建某个对象的
第一,先实例A对象,同时会创建ObjectFactory对象存入三级缓存singletonFactories
第二,A在初始化的时候需要B对象,这个走B的创建的逻辑
第三,B实例化完成,也会创建ObjectFactory对象存入三级缓存singletonFactories
第四,B需要注入A,通过三级缓存中获取ObjectFactory来生成一个A的对象同时存入二级缓存,这个是有两种情况,一个是可能是A的普通对象,另外一个是A的代理对象,都可以让ObjectFactory来生产对应的对象,这也是三级缓存的关键
第五,B通过从通过二级缓存earlySingletonObjects 获得到A的对象后可以正常注入,B创建成功,存入一级缓存singletonObjects
第六,回到A对象初始化,因为B对象已经创建完成,则可以直接注入B,A创建成功存入一次缓存singletonObjects
第七,二级缓存中的临时对象A清除
事务的传播机制
Springboot自动配置原理
嗯,好的,它是这样的。
在Spring Boot项目中的引导类上有一个注解@SpringBootApplication,这个注解是对三个注解进行了封装,分别是:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
其中@EnableAutoConfiguration是实现自动化配置的核心注解。
该注解通过@Import注解导入对应的配置选择器。关键的是内部就是读取了该项目和该项目引用的Jar包的的classpath路径下META-INF/spring.factories文件中的所配置的类的全类名。
在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入到Spring容器中。
一般条件判断会有像@ConditionalOnClass这样的注解,判断是否有对应的class文件,如果有则加载该类,把这个配置类的所有的Bean放入spring容器中使用。
SpringMVC流程
用户发起请求,请求先被 Servlet 拦截转发给 Spring MVC 框架
Spring MVC 里面的 DispatcherServlet 核心控制器,会接收到请求并转发给HandlerMapping
HandlerMapping 负责解析请求,根据请求信息和配置信息找到匹配的 Controller类,不过这里如果有配置拦截器,就会按照顺序执行拦截器里面的 preHandle方法
找到匹配的 Controller 以后,把请求参数传递给 Controller 里面的方法
Controller 中的方法执行完以后,会返回一个 ModeAndView,这里面会包括视图名称和需要传递给视图的模型数据
视图解析器根据名称找到视图,然后把数据模型填充到视图里面再渲染成 Html 内容返回给客户
评论区