面试篇-Spring-1+ioc+bean的生命周期+aop+事务支持+循环依赖


前言

你们项目中使用过Spring吗,你知道Spring 的IOC和AOP吗,你知道bean的工作过程吗,你知道Spring 是怎么解决循环依赖吗,Spring 中的事务底层实现原理是怎样的。本文重点对面试的问题进行介绍,祝愿每位程序员都能顺利上岸!!!


一、你知道Spring的Ioc:

Spring IOC作为Spring 的两大特性之一,它将Bean 的创建和销毁过程进行了管理,使得程序员可以只关注bean 的使用。

1.1 那你知道bean 的生命周期吗

Spring容器在进行实例化时,会将xml配置的的信息或者通过注解定义的bean 类,封装成一个BeanDefinition对象,Spring根据BeanDefinition来创建Bean对象,里面有很多的属性用来描述Bean。
在这里插入图片描述

一个bean的 生命周期包括bean 的创建,依赖注入,初始化,aop代理,使用,销毁几个过程;
在这里插入图片描述
并且在bean 的创建过程中,还提供了多个扩展 方法。
在这里插入图片描述

1.2 你知道Spring 中的bean 都有哪些类型吗:

Spring全家桶源码解析–2.6 Spring scope 限制bean的作用范围

  • 单例bean :系统中使用最多的bean,spring 中默认生成的bean 都是单例bean;
  • 原型bean: 多例bean,每次使用该bean 都会生成一个新的bean;
  • 请求requestbean:web 场景下,不同的请求,创建的对象不同,在同一次请求内,bean 对象是相同的;
  • 会话sessionbean :web 场景下,浏览器同一个会话,使用到的对象是相同的;

1.3 你知道 beanFactory,factoryBean的区别吗:

  • beanFactory这个其实是所有Spring Bean的容器根接口,给Spring 的容器定义一套规范,给IOC容器提供了一套完整的规范,比如我们常用到的getBean方法等;
  • factoryBean该类是SpringIOC容器是创建Bean的一种形式,这种方式创建Bean会有加成方式,融合了简单的工厂设计模式于装饰器模式,通过T getObject():返回实例;

1.4 你知道 BeanFactory和ApplicationContext的区别吗:

  • BeanFactory 是最顶层的接口,最主要功能就是各种获取Bean的方法。
  • ApplicationContext同样是有BeanFactory派生出来的,提供了很多面向实际应用的功能,主要接口 ApplicationContext 继承与 ListableBeanFactory、HierarchicalBeanFactory、ApplicationEventPublisher:提供容器发布上下文事件的功能,如容器启动事件,关闭事件等实现了ApplicationListener就可以接收处理到这些事件。

1.5 Spring 中的bean 是线程安全的吗

Spring 中定义的bean 默认都是单例的,所以我们在代码中注入的bean 对象实际上是同一个,但这并不意味着单例bean 是线程安全的,单例bean 的安全性,取决于改bean的实例是否状态安全的,比如我们在一个bean 中定义了一个可以被修改的成员变量,此时就需要考虑加锁,或者将bean的作用由“singleton"变更为"prototype”。

1.6 你都知道哪些方式可以破坏单例bean,应该怎么避免呢

  • 可以通过反射方式调用构造方法再次生成一个bean 的实例对象;解决办法是定义一个全局变量,如果bean已经存在,再次调用构造方法,可以报错或者返回已经创建好的bean

  • 调用bean 对象的 clone方法克隆出来一个新的bean 对象 :解决办法是: clone 通过在内存中将对象拷贝出来一个副本,破坏单例bean,重写clone 方法,返回已经创建好的bean;

  • 通过反序列化来创建一个bean对象:解决办法是:在反序列化时的回调方法 readResolve()中返回已存在的单例对象。

1.7 你知道spring 是怎么解决循环依赖问题吗

spring 中的循环依赖通过三级缓存进行了处理。详细原理可以参考: Spring大白话–三级缓存解决循环依赖问题

1.7.1 什么是循环依赖

在这里插入图片描述A和B 类彼此引用:
在这里插入图片描述

1.7.2 什么是三级缓存

Spring 中的三级缓存,通过提前暴露bean 来解决循环依赖的问题。
在这里插入图片描述

1.7.2.1 一级缓存

一级缓存用来存放已经初始化完成的bean

在这里插入图片描述

1.7.2.2 一级缓存+二级缓存

二级缓存存放半成品的对象,打破循环依赖

在这里插入图片描述

1.7.2.2 一级缓存+二级缓存+三级缓存处理代理对象

在这里插入图片描述

1.7.3 你们项目中有没有出现spring 三级缓存解决不了的循环依赖,你们是怎么处理的

  • 项目中使用了构造方法进行bean 的注入,但是多个类实例化的入参,出现了循环的引用;因为无法完成对象实例的创建,所以走不到后续的三级缓存,启动会报错。
  • 项目中使用了@Async 异步线程的注解,当出现循环引用时,回先生成该类的一个普通对象,进行类的属性注入;然而到该类进行初始化后为其创建了代理对象,暂存另一个类注入的对象,与此时生成的代理对象不是同一个对象,启动报错;
  • 当出现以上情况时,我们通过@Lazy延迟加载,可以通过将 bean 的依赖关系运行时进行注入,而不是在初始化阶段。这样,当遇到循环依赖时,Spring 可以先创建需要的 bean 实例,并将其设置为代理对象,而不需要立即解决依赖关系。

二、你们项目中有用到Spring的Aop吗,你们都使用aop做过哪些处理

AOP称为面向切面编程,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。

2.1 你知道Aop 切面的实现吗

2.1.1 Spring 切面的使用:

可以参考:还在思索Spring-Aop 吗?,那么来一起畅游Spring吧–Spring系列开篇之 Spirng-Aop篇

2.2 你们项目中都用过aop 做过什么

2.2.1 使用aop 进行日志记录

我们在项目中通过自定义了@Log的注解,然后在需要记录日志的方法可以太耐改注解,然后通过定义@Aspect 切面类,定义切点,以及前置方法和后置方法,可以实现记录方法的方法,访问的参数,返回的结果以及耗时,然后定义了线程池,将数据报错的Mysql 或者Es 中。

在这里插入图片描述

2.2.2 使用aop 进行数据的事务处理

2.2.2.1 你知道@Transaction 的原理吗:

Spring支持编程式事务管理和声明式事务管理两种方式。
编程式事务控制:需使用TransactionTemplate来进行实现,对业务代码有侵入性,项目中很少;
使用声明式事务管理:声明式事务管理建立在AOP之上的。其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

在这里插入图片描述

2.2.2.2 你们有没有遇到过事务失效的情况

通常在项目中我们使用声明式事务,来对数据进行事务处理;事务失效我在项目中遇到主要有以下三种:

  • 方法非public
  • 使用try catch 吞掉了异常,而且没有继续向外抛出异常
  • 抛出了检查异常

1)捕获了异常但是没有继续向外抛
在这里插入图片描述
2) 抛出检查异常:
在这里插入图片描述3)非public 方法:
在这里插入图片描述

2.2.2.3 你知道事务的传播吗

多个事务方法相互调用时,事务如何在这些方法间传播,方法A是一个事务的方法,方法A执行过程中调用了方法B,那么方法B有无事务以及方法B对事务的要求不同都会对方法A的事务具体执行造成影响,同时方法A的事务对方法B的事务执行也有影响,这种影响具体是什么就由两个方法所定义的事务传播类型所决定。

  • REOUIRED(Spring默认的事务传播类型):如果当前没有事务,则自己新建一个事务,如果当前存在事务,则加入这个事务
  • SUPPORTS:当前存在事务,则加入当前事务,如果当前没有事务,就以非事务方法执行
  • MANDATORY:当前存在事务,则加入当前事务,如果当前事务不存在,则抛出异常。
  • REQUIRES NEW:创建一个新事务,如果存在当前事务,则挂起该事务。
  • NOTSUPPORTED:以非事务方式执行,如果当前存在事务,则挂起当前事务
  • NEVER:不使用事务,如果当前事务存在,则抛出异常
  • NESTED:如果当前事务存在,则在嵌套事务中执行,否则REQUIRED的操作一样(开启一个事务)

总结

本文对Spring 框架中,常见的如:Spring bean 的生命周期,bean 的循环依赖,Aop 以及事务的底层原理面试问题进行总结。

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值