1.对IOC的理解
概述:
Inversion Of Control:将对象的创建权交由spring的IOC容器来管理。程序如果需要对象,从
spring的IOC容器中获取。
IOC也称为依赖注入(DI),这是一个过程,对象通过构造函数参数、工厂的参数或在对象实例被构造或从工厂方法返回后设置属性来定义他们的依赖关系,然后容器在创建bean时注入这些依赖项。这个过程基本就是bean本身通过使用类的直接构造或者诸如服务定位器模式之类的机制来控制其依赖关系的实例化或者位置的逆过程,因此被称为控制反转。
作用:
降低类与类之间的耦合。
扩展:
在Spring中,构成应用程序主干并由Spring IOC 容器管理的对象称为bean,bean是由Spring IoC容器实例化、组装和管理的对象bean以及他们之间的依赖关系反应在容器使用的配置元数据中。
2.Spring Bean 生命周期的执行流程
- 实例化bean对象
通过反射的方式进行对象的创建,此时的创建只是在堆空间中申请空间,属性都是默认值
- 设置对象属性
给对象中的属性进行值的设置工作
- 检查Aware相关接口并设置相关依赖
如果对象中的需要引用容器内部的对象,那么需要调用aware接口的子类方法来进行统一设置
- BeanPostProcessor的前置设置
对生成的bean对象进行前置的处理工作
- 检查是否是InitializingBean的子类来决定是否调用afterPropertiesSet方法
判断当前bean对象是否设置了InitializingBean接口,然后进行属性的设置等基本工作
- 检查是否配置有自定的init-method方法
如果当前bean对象定义了初始化方法,那么再次调用初始化方法
- BeanPostProcessor后置处理
对生成的bean对象进行后置的处理工作
- 注册必要的Destruction相关回调接口
为了方便对象的销毁,在此处调用注销的回调接口,方便对象进行销毁操作
3.spring事务什么时候会失效。
- 数据库不支持事务
- 事务方法未被spring管理
- 方法没有被public修饰
产生原因:Spring为方法创建代理、添加事务通知、前提条件都是该方法是public的
解决措施:改为public方法。
- 同一类中方法调用
- 未配置事务管理器
- 方法的事务传播类型不支持事务
- 不正确的捕获异常
产生原因: 事务通知只有捉到了目标抛出的异常,才能进行后续的回滚操作,如果目标自己处理掉异常,事务通知无法感知。
解决措施: 在catch块中添加throw new RuntimeException(e)抛出。
- 错误的标注异常类型
原因: Spring默认只会回滚非检查异常
解决措施:配置rollbackFor属性 @Transaction(rollbackFor=Exception.class)
4.spring如何解决循环依赖
循环依赖产生的原因:
在代码中,将两个或者多个bean互相之间持有对方的引用就会发生循环依赖。循环的依赖将会导致注入死循环,这是Spring产生循环依赖的原因
循环依赖的三种形式:
- 第一种互相依赖:A 依赖B,B 又依赖A,它们之间形成了循环依赖。
- 第二种三者间依赖:A 依赖B,B 依赖C,C 又依赖A,形成了循环依赖。
- 第三种是自我依赖:A 依赖A 形成了循环依赖
如何解决循环依赖:
Spring设计了三级缓存来解决依赖问题。
当我们调用getBean()方法时,Spring会先从一级缓存去找目标Bean,如果发现一级缓存中没有便会从二级缓存中寻找,而如果一、二级缓存中都没有找到,便意味着改目标Bean还没有实例化。于是,Spring容器便会实例化目标Bean。然后,将目标Bean放入到二级缓存中,同时加上标记是否存在循环依赖。如果不存在循环依赖便会将目标Bean存入二级缓存(放入二级缓存,避免多重循环依赖,重复创建动态代理),否则,便会标记该Bean存在循环依赖,然后等待下次轮询赋值,也就是解析@Atuowired注解。等该注解赋值完成之后,会将目标Bean存入至一级缓存。
5、什么是AOP,以及AOP的使用场景
AOP称为面向切面编程,用于将那些与业务无关,但是却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。
常见的AOP使用场景:
- 记录操作日志:
核心是:使用AOP的环绕通知+切点表达式(找到要记录日志的方法),通过环绕通知的参数获取请求方法的参数(类、方法、注解、请求方式等),获取到这些参数以后,保存到数据库。
- 缓存处理:
- Spring中内置的事务处理:
通过声明式事务实现的,本质是通过AOP功能,对方法前后进行拦截,在执行方法之前开启事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
6、SpringMVC执行流程:
SpringMVC中重要的组件:
前端控制器、处理器映射器、处理器适配器、视图解析器
版本2:
7、SpringBoot自动配置原理:
1、在Springboot项目中的引导类上有一个注解@SpringBootApplication,这个注解是对三个注解进行了封装,分别是:
@SpringBootConfiguration :表明当前类为一个配置类。 @EnableAutoConfiguration @ComponentScan2、其中@EnableAutoConfiguration是实现自动化配置的核心注解。该注解通过@Import注解导入对应的配置选择器。内部就是读取了该项目和该项目引用的Jar包的classpath路径下META-INF/spring.factories文件中的所配置的类的全类名。在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入Spring容器中。
3、条件判断会有像@conditionalOnClass这样的注解,判断是否有对应的Class文件,如果有则加载该类,把这个配置类的所有Bean放入spring容器中使用。
8、Spring的三级缓存:
Spring框架中的缓存分为三级,分别是对象级缓存、单例对象级别的缓存和单例Bean工厂级别的缓存。
1.对象级缓存
对象级缓存是指Spring在创建Bean对象的时候,将这些对象放入缓存中,以便下次需要这些对象时,可以直接从缓存中获取,而不需要再次创建。这种缓存是针对原型作用域的Bean对象设计的。
2.单例对象级别的缓存
单例对象级别的缓存是指Spring框架在实例化单例Bean时,将这些Bean对象缓存起来,这些缓存的Bean对象可以跨多个Bean工厂使用。如果同样的Bean请求多次,Spring将会重用已有的Bean实例,而不是新建实例。这种缓存是Spring框架默认的缓存实现方式。
3.单例Bean工厂级别的缓存
单例Bean工厂级别的缓存是指Spring框架在实例化Bean实例时,为整个容器的单例Bean工厂维护了一个缓存,以便重用Bean实例。这种缓存的Bean对象可被所有在当前Spring容器中创建的Bean对象所共享,它们共享一个单例的Bean实例。这种缓存方式通常用于Spring框架内部缓存实现中。
所谓的早提提前暴露的对象就是说,你是一个不完整的对象,你的属性还没有值,你的对象也没有被初始化。这就是早期暴露的对象,只是提前拿出来给你认识认识。
使用Spring三级缓存机制可以有效地提高应用性能和可扩展性