spring 面试题

2021/04/10

spring 是如何创建一个bean对象得

UserService类 –>无参得构造方法–>对象–>依赖注入–>初始化前(@PostConstruct)–>初始化(InitializingBean)–>初始化后(AOP)–>代理对象–>放入map单例池–>bean对象

基于类得无参构造方法 创建对象,依赖注入属性,放到map单例池中

什么是单例池?作用是什么

底层用map来存map<beanName ,Bean对象>

@PostConstruct注解是如何工作得

bean初始化前 调用@PostConstruct注解

bean得初始化如何工作的

实现InitializingBean接口的,调用afterPropertiesSet()方法

bean的初始化和实例化区别是什么

初始化:是执行afterPropertiesSet方法

实例化:基于类的无参构造方法 实例化一个对象

什么是初始化后

aop 动态代理 代理对象

推断构造方法是什么意思

一个类如果有多个构造方法,spring会寻找无参构造方法。如果没有无参构造方法,就会报错,使用autowired告诉spring使用哪个构造方法,避免报错

什么是先bytype再byName

参数为bean是,先根据type找bean,如果有多个,根据name选择

什么是循环依赖

创建userservice 需要orderservice,此时会去创建orderservice,结果创建orderservice 又需要userservice,这就是循环依赖

spring为什么用三级缓存解决循环依赖

Aservice 创建生命周期

  1. 创建一个AService普通对象 —>放入map中Map<beanName,Aservice普通对象>
  2. 填充bService属性 –> 去单例池中找BService对象–> 创建BService的bean对象
  3. 填充其他属性
  4. 初始化后
  5. 放入单例池

Bservice 创建生命周期

  1. 创建一个BService普通对象

  2. 填充AService属性 –> 去单例池中找AService对象–> 创建AService的bean对象

  3. 填充其他属性

  4. 初始化后

  5. 放入单例池

  6. 单例池 singletonObjects 一级缓存

  7. earlySingletonOBbjects 二级缓存

  8. 三级缓存 singleonFactories

一级缓存存的普通对象。二级缓存存的是代理对象,三级缓存存的lambda表达式,用来打破循环,

Spring aop 底层是怎么工作的

spring事务底层是怎么工作

@Transactional 事务管理器 建立一个数据库连接conn

coon.autocomit =false

target.test() 普通对象.test() sql1 sql2 sql3

成功: conn.commit(); 失败: conn.rollback()

事务失效的情况:

1、spring的事务注解@Transactional只能放在public修饰的方法上才起作用,如果放在其他非public(private,protected)方法上,虽然不报错,但是事务不起作用

2、如果采用spring+spring mvc,则context:component-scan重复扫描问题可能会引起事务失败。

​ 如果spring和mvc的配置文件中都扫描了service层,那么事务就会失效。

​ 原因:因为按照spring配置文件的加载顺序来讲,先加载springmvc配置文件,再加载spring配置文件,我们的事物一般都在srping配置文件中进行配置,如果此时在加载srpingMVC配置文件的时候,把servlce也给注册了,但是此时事物还没加载,也就导致后面的事物无法成功注入到service中。所以把对service的扫描放在spring配置文件中或是其他配置文件中。 3、如使用mysql且引擎是MyISAM,则事务会不起作用,原因是MyISAM不支持事务,可以改成InnoDB引擎

4、在业务代码中如果抛出RuntimeException异常,事务回滚;但是抛出Exception,事务不回滚;

解决方法@Transactional改为@Transactional(rollbackFor = Exception.class)

5、如果在加有事务的方法内,使用了try…catch..语句块对异常进行了捕获,而catch语句块没有throw new RuntimeExecption异常,事务也不会回滚

6、在类A里面有方法a 和方法b, 然后方法b上面用 @Transactional加了方法级别的事务,在方法a里面 调用了方法b, 方法b里面的事务不会生效。原因是在同一个类之中,方法互相调用,切面无效 ,而不仅仅是事务。这里事务之所以无效,是因为spring的事务是通过aop实现的