文章目录
- 1、你了解Spring IOC吗?
- 2、SpringIOC的应用?
- 3、SpringIOC的getBean方法的解析?
- 4、面试题
- 5、你了解Spring AOP吗?
- 6、事务ACID特性
- 7、事务传播
1、你了解Spring IOC吗?
IoC(Inversion of control):控制反转
- Spring Core最核心的部分
- 需要先了解依赖注入(Dependency Inversion)
IOC:是一个思想。
DI举例:
如果,轮子改变的话,整体的都是需要改变的。
正确的注入的方式:
控制反转(IOC):控制反转,由自己的控制,转为容器进行控制管理。
依赖注入,是上层的类,注入底层的类。也就是只有4个类的内存空间。上面的是每次都new对象,开辟了双份的内存空间。
依赖注入的方式:
- Setter:
- Interface
- Constructor:构造器
- Annotation:注释,注解。
依赖倒置原则、IOC、DI、IOC容器的关系:
依赖倒置原则:高层模块不能依赖底层模块,应该依赖其抽象。
IOC容器的优势:
- 避免在各处使用new来创建类,并且可以做到统一维护。
- 创建实例的时候不需要了解其中的细节。
2、SpringIOC的应用?
Spring提供一个配置文件,描述Bean以及Bean之间的依赖关系,利用Java语言的反射功能实例化Bean,并建立Bean之间的依赖关系。
- 读取Bean配置信息,并在Spring容器中生成一份Bean配置注册表。
- 根据Bean注册表实例化Bean。
- 将Bean实例放到Spring容器中。
- 使用Bean。
Spring 功能
Spring IOC支持的功能
- 依赖注入
- 依赖检查
- 自动装配
- 支持集合
- 指定初始化方法和销毁方法
- 支持回调方法
Spring IOC容器的核心接口
- BeanFactory
- ApplicationContext
BeanDefinition()
主要用来描述Bean的定义
将XML和注解里Bean,解析为Spring内部的BeanDefinition
Bean Definition Registry
提供向IOC容器注册 BeanDefinition对象的方法
以Bean为Key,BeanDefinition为value,存在BeanDefinitionMap中。并将名称存在beanDfinitionNames中,以便后续Bean的实例化。
BeanFactory体系结构
BeanFactory和ApplicationContext的比较?
- Bean Factory是 Spring框架的基础设施,面向 Spring
- ApplicationContext面向使用 Spring框架的开发者
ApplicationContext的功能(继承多个接口)
- Bean Factory:能够管理、装配Bean。
- ResourcePatternResolver:能够加载资源文件。
- MessageSource:能够实现国际化等功能。
- ApplicationEventPublisher:能够注册监听器,实现监听机制。
3、SpringIOC的getBean方法的解析?
geBean的实现AbstractBeanFactory方法。
getBean方法的代码逻辑
- 转换 beanName
- 从缓存中加载实例
- 实例化Bean
- 检测 parentBeanFactory
- 初始化依赖的Bean
- 创建Bean
4、面试题
Spring Bean的5个作用域?
创建和销毁Bean很消耗资源
在Spring框架中,可以通过配置和注解来定义和管理对象的生命周期和作用域。Spring Bean的作用域定义了对象实例的创建和销毁方式以及对象在应用程序中的可见性。下面是Spring Bean的五个作用域:
- Singleton(默认作用域)(唯一):
单例作用域表示在整个应用程序中只创建一个对象实例。当使用singleton作用域时,Spring容器只会创建一个共享的Bean实例,并在需要时返回该实例。每次请求该Bean时都会返回同一个实例。
- Prototype(原型作用域)(每次请求):
原型作用域表示每次请求时都会创建一个新的对象实例。每次从容器中获取Bean时,都会返回一个新的独立实例。原型作用域适用于需要每次使用时都获得一个全新实例的场景。
- Request(每个Http):
请求作用域表示每个HTTP请求都会创建一个新的对象实例。在Web应用程序中,每个HTTP请求都会创建一个独立的Bean实例,并且该实例在整个请求范围内是共享的。适用于每个HTTP请求需要使用不同实例的场景。
- Session(每个会话):
会话作用域表示每个用户会话都会创建一个新的对象实例。在Web应用程序中,每个用户会话都会创建一个独立的Bean实例,并且该实例在整个会话期间是共享的。适用于需要跨多个请求共享状态的场景。
- Global Session(全):
全局会话作用域是在基于Portlet的Web应用程序中使用的作用域,它表示整个应用程序的生命周期。在非Portlet环境中,全局会话作用域与标准会话作用域相同。
以上是Spring框架中常用的五个Bean作用域。通过选择适当的作用域,可以控制对象的生命周期和共享方式,以满足应用程序的需求。
Spring Bean的声明周期
创建过程:
销毁过程:
- 若实现了 DisposableBean 接口,则会调用 destroy方法。
- 若配置了 destry-method 属性,则会调用其配置的销毁方法。
5、你了解Spring AOP吗?
关注点分离:不同的问题交给不同的部分去解决
- 面向切面编程AOP正是此种技术的体现
- 通用化功能代码的实现,对应的就是所谓的切面(Aspect)
- 业务功能代码和切面代码分开后,架构将变得高内聚低耦合
- 确保功能的完整性:切面最终需要被合并到业务中(Weave)
AOP的三种织入方式
- 编译时织入:需要特殊的Java编译器,如 AspectJ。
- 类加载时织入:需要特殊的Java编译器,如 AspectJ和 AspectWerkz。
- 运行时织入:Spring采用的方式,通过动态代理的方式,实现简单。
AOP的主要名词概念:
- Aspect:通用功能的代码实现
- Target:被织入 Aspect的对象
- Join point:可以作为切入点的机会,所有方法都可以作为切入点
- Pointcut:Aspect实际被应用在的 Join point,支持正则
- Weaving:Aop的实现过程
Advice的种类
- 前置通知(Before)
- 后置通知(AfterReturning)
- 异常通知(AfterThrowing)
- 最终通知(After)
- 环绕通知(Around)
AOP的实现:JakProxy和 Cglib
- 由 Aop Factory根据 AdvisedSupport对象的配置来决定
- 默认策略如果目标类是接口,则用 JDKProxy(JDK动态代理)来实现,否则用后者
- JDKProxyl的核心:Invocation Handler接口和 Proxy类
- cglb:以继承的方式动态生成目标类的代理
JDKProxy:通过ava的内部反射机制实现
Cgib:借助ASM实现
反射机制在生成类的过程中比较高效
ASM在生成类之后的执行过程中比较高效
代理模式:
接口+真实实现类+代理类(生成一个代理类,代理真实的类,对外提供服务)
Spring里的代理模式的实现
- 真实实现类的逻辑包含在了 getBean方法里
- getBean方法返回的实际上是Proxy的实例
- Proxy实例是 Spring采用 JDK Proxy或CGLB动态生成的
- Spring事务的相关考点
6、事务ACID特性
数据库事务正确执行的4个基础要素是:原子性(Atomicity),一致性(Consistency),隔离性(Isolation)和持久性(Durability)
原子性(Atomicity): 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency): 事务前后数据的完整性必须保持一致。
隔离性(Isolation): 事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。
持久性(Durability): 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
并发访问问题:
脏读:一个事务读到了另一个事务未提交的数据.
不可重复读:个事务读到了另一个事务已经提交(update)的数据。引发另一个事务,在事务中的多次查询结果不一致。
虚读/幻读:一个事务读到了另一个事务已经提交(insert)的数据。导致另一个事务,在事务中多次查询的结果不一致。
隔离级别:解决问题
读未提交(read uncommitted):最低的隔离级别,含义是允许一个事务去读取另一个事务未提交的数据。
读已提交(read committed):是说一个事务只能读取另一个事务已经提交的数据。
可重复读(repeatable read):针对数据库中同一条记录而言,使得同一条数据库记录的读写按照一个序列化进行操作,不会产生交叉情况,这样就能保证同一条数据的一致性。
串行化(serializable):一种让SQL按照顺序读写的方式,能够消除数据库事务之间并发产生数据不一致的问题。
7、事务传播
@Transactional(propagation=Propagation.REQIRED)
public class FlowService{
}
- requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。
- supports:支持当前事务,如果没有当前事务,就以非事务方法执行。
- mandatory:使用当前事务,如果没有当前事务,就抛出异常。
- required_new:新建事务,如果当前存在事务,把当前事务挂起。
- not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- never:以非事务方式执行操作,如果当前事务存在则抛出异常。
- nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作