Spring 框架的好处
1、轻量:spring是轻量的,基本的版本大约2MB;
2、IOC:控制反转,Spring的IOC机制使得对象之间的依赖不再需要我们自己来控制了,而是由容易来控制,一个字:爽;
3、AOP:切面编程,Spring提供的AOP技术可以把应用逻辑和系统服务分来,编码更灵活,更方便;
4、MVC框架:如果使用过Struts2的同学,使用springmvc就会觉得非常的舒适,spring提供的mvc框架是一个非常优秀的Web框架;
5、全局事务管理:Spring提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务;
6、统一异常处理:
Autowired 和 Resource 注解的区别
共同点:都是做bean注入时使用的,都可以写在字段或者setter方法上面;
不同点:
1、包归属不同,@Autowired是Spring提供的注解,@Resource是javax提供的注解;
2、寻找bean的方式不同,@Resource默认是优先根据名称查找bean,而@Autowired默认是优先根据类型查找bean
SpringMVC的运行机制
这个问题已经很古老的,很多面试官也不会问,因为大家的侧重点都是在分布式高并发还有场景问题上。SpringMVC的处理请求过程或者说运行机制吧,大家可以通过设计模式的方式来去学习。
MVC模式
MVC分别代表了Model、View、Controller三个处理节点
C:控制器层,用于接受请求,调用业务类,最后派发页面;
M:数据模型层(包含service、dao、entity)主要是处理业务数据并返回处理结果;
V:视图渲染层,主要为了渲染页面。
在当前前后端分离已经成为了一个常态的情况下,V已经逐渐淡化了,但是在5年前前后端分离还没有那么的成熟,如果回到2016年,当时主流前端线下课都还没有vue2的课程存在,就是三大框架+jquery;那么mvc这个模式就是老子天下第一;
工作原理
springmvc主要通过中央处理器(DispatcherServlet)来统一调度。如下图所示
Bean的生命周期
经典的问题。提到生命周期,我们应该想到的是spring能够IOC其实就是保存了一个bean的实例池,所以生命周期的前期一定是实例化和初始化,实例化就是把对象在内存空间中分配出来,初始化就是给对象的属性赋值。当一个bean完成了使命后就要面临销毁,就会有一个销毁的过程。
只不过为了方便扩展,spring把实例化和初始化的过程进行了多重封装,方便开发者去介入bean的实例化过程。具体如下:
1、实例化 Bean :
对于 BeanFactory 容器,当客户向容器请求一个尚未初始化的 bean 时,或初始化 bean 的时候需要 注 入 另 一 个 尚 未 初 始 化 的 依 赖 时 , 容 器 就 会 调 用 createBean 进 行 实 例 化 。 对于 ApplicationContext容器,当容器启动结束后,通过获取 BeanDefinition 对象中的信息,实例 化所有的 bean。
2、设置对象属性(依赖注入):
3、处理 Aware 接口:
接着,Spring 会检测该对象是否实现了 xxxAware 接口,并将相关的 xxxAware 实例注入 Bean :
- 如果这个 Bean 已经实现了 BeanNameAware 接口,会调用它实现的 setBeanName(String beanId)方法,此处传递的就是 Spring 配置文件中 Bean 的 id 值;
- 如果这个 Bean 已经实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory()方法,传递的是 Spring 工厂自身。
- 如果这个 Bean 已经实现了 ApplicationContextAware 接口,会调用setApplicationContext (ApplicationContext)方法,传入Spring上下文;
4、BeanPostProcessor:
如果想对 Bean 进行一些自定义的处理,那么可以让 Bean 实现了 BeanPostProcessor 接口,那将会调用 postProcessBeforeInitialization(Object obj, Strings)方法。
5、InitializingBean 与 init-method :
如果 Bean 在 Spring 配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法
6、 如果这个Bean实现了BeanPostProcessor 接口,将会调用postProcessAfterInitialization (Object obj, Strings)方法;由于这个方法是在 Bean 初始化结束时调用的,所以可以被应用于内存或缓存技术;
7、DisposableBean
当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 这个接口,会调用其实现 的 destroy()方法;
8、destroy-method
最后,如果这个 Bean 的 Spring 配置中配置了 destroy-method 属性,会自动调用其配置的销 毁方法。
spring框架中都用到了哪些设计模式
1、简单工厂模式 :Spring 中的 BeanFactory 就是简单工厂模式的体现。根据传入一个唯一的标识来获得Bean 对象,但是在传入参数后创建还是传入参数前创建,要根据具体情况来定。
Spring是怎么解决循环依赖的?
一句话就是spring是通过三级缓存来解决循环依赖的,所以如果有人问spring的三级缓存是干什么的,也是一样的,是解决循环依赖问题的。具体来说,就是A依赖B,B依赖C,C又依赖了A,产生了循环。spring在实例化Bean的过程中,当发现有一个属性是对象,就会尝试去获取这个对象的bean,递归调用又调用回来了,发现自身还在创建中,那么说明发生了循环依赖。解决流程如下:
1、A先初始化第一步提前把自己暴露出来,(通过一个对象工厂的方式存在三级缓存中),
当发现依赖对象B时,就尝试获取B的bean;
2、B没有创建,走创建流程,发现自己依赖的C也没有创建;
3、C走创建流程,发现依赖A,此时A在三级缓存中,通过 ObjectFactory#getObject() 方法来拿到 A 对象,此时C顺利完成初始化,并将自己添加到一级缓存中;
4、B拿到了C的bean,也完成了初始化,将自己添加到一级缓存中;
5、A又拿到了B的bean,完成了初始化,将自己添加到一级缓存中;
Spring事务传播级别
Spring 事务定义了 7 种传播机制:
1. PROPAGATION_REQUIRED:默认的 Spring 事务传播级别,若当前存在事务,则加入该事务,若不存在事务,则新建一个事务。
2. PAOPAGATION_REQUIRE_NEW:若当前没有事务,则新建一个事务。若当前存在事务,则新建一个事务,新老事务相互独立。外部事务抛出异常回滚不会影响内部事务的正常提交。
3. PROPAGATION_NESTED:如果当前存在事务,则嵌套在当前事务中执行。如果当前没有事务,则新建一个事务,类似于 REQUIRE_NEW。
4. PROPAGATION_SUPPORTS:支持当前事务,若当前不存在事务,以非事务的方式执行。
5. PROPAGATION_NOT_SUPPORTED:以非事务的方式执行,若当前存在事务,则把当前事务挂起。
6. PROPAGATION_MANDATORY:强制事务执行,若当前不存在事务,则抛出异常.
7. PROPAGATION_NEVER:以非事务的方式执行,如果当前存在事务,则抛出异常。