1.spring 中都用到了哪些设计模式?
spring中用到的设计模式有
- 工厂模式(BeanFactory和ApplicationContext)生产Bean对象
- 代理设计模式 (AOP的实现是通过代理来实现的,spring使用jdk动态代理和CGLIB代理)
- 单例设计模式(spring中的bean都是单例的)
- 模板方法模式(以Template结尾的对数据库操作的类比如jdbcTemplate)
- 包装器设计模式(用途就是切换不同的数据源)
- 观察者模式(spring事件驱动模型观察)
- 适配器模式(springAOP的增强或者通知使用到了适配器模式)
前4种掌握,后面的3种了解即可
2.spring的核心模块?
上图介绍:
1.spring Core 是spring的核心,框架最基础的部分,提供IOC和DI特性
2.Context 是spring的上下文
3.spring Web 支持Web开发
4.Spring MVC 是Web应用MVC思想的实现
5.Spring DAO 简化JDBC编码,让代码更加健壮
6.SPring ORM 支持流行的ORM框架
7.Spring AOP 面向切面编程
3.谈谈对IOC的理解?
首先解释一下IOC
IOC是一个容器,是用来装载对象的,他的核心思想是控制反转.
接着说明什么是控制反转?
控制反转就是说,把对象的控制权交给spring,由spring容器进行管理,我们不进行任何操作
最后说为什么需要控制反转?
如果没有控制反转,我们就需要自己去创建对象,配置对象,还要人工处理对象与对象之间的复杂依赖关系.当工程大的时候就有很多对象需要进行维护,,维护起来很麻烦,这时就有了控制反转这个该概念,将对象的创建与管理交给spring容器去做,我们用的时候,从容器去取就行.
4.spring中的IOC容器有那些?有什么区别?
spring主要提供了两种IOC容器,一种时BeanFactory另一种是ApplicationContext
区别:
BeanFactory只提供了最基本的实例化对象和拿对象的功能
而ApplicationContext是继承BeanFactory所派生出来的产物,是其子类,所以功能更加强大,比如支持注解等
5.BeanFactory和FactoryBean又有什么区别?
这两个完全是不同的产物
BeanFactory是IOC容器,用来承载对象
FactoryBean是一个接口,为bean提供更加灵活的方式,通过代理一个bean对象,对方法前后做一些操作
6.@Repository,@Service,@Compent,@Controller他们有什么区别?
共同点:本质是一样的,都是IOC的注解,被该注解标注,都将放入springIOC容器中,只是使用的层不同:
@Repository:dao层
@Service: service层
@Controller: controller层
@Compent 其他不属于以上三层的统一使用该注解
7.那么DI又是什么呢?
DI就是依赖的注入
IOC的核心功能就是依赖的注入,DI简单理解就是进行属性赋值
依赖注入的方式:
构造方法
set注入
P命名空间注入
8.说说AOP是什么?
AOP:面向切面编程,通过预编译方式和运行时间动态代理实现程序的统一维护的一种技术
AOP是OOP的一种延续,使业务逻辑耦合度降低,提高程序的可重用性,提高开发效率
AOP实现主要分两类:
[静态AOP实现] AOP在编译阶段对程序源代码进行修改,生成静态的AOP代理类
[动态AOP实现] AOP在运行阶段生成代理对象(JDK或CGLIB代理)
通知类型:
9.JDK动态代理和CGLIB代理的区别?
JDK动态代理必须要实现某个接口,它是基于反射的机制实现的,生成代理对象,通过重写方法,实现代码的增强.
CGLIB动态代理是基于类的,创建子类,然后重写父类方法,实现增强.
10.spring中Bean的生命周期?
-
1.「实例化」,实例化该 Bean 对象
-
2.「填充属性」,给该 Bean 赋值
-
3.「初始化」
-
如果实现了 Aware 接口,会通过其接口获取容器资源
-
如果实现了 BeanPostProcessor 接口,则会回调该接口的前置和后置处理增强
-
如果配置了 init-method 方法,]会执行该方法
-
-
4.「销毁」
-
如果实现了 DisposableBean 接口,则会回调该接口的 destroy 方法
-
如果配置了 destroy-method 方法,则会执行 destroy-method 配置的方法
-
11.spring是怎么解决循环依赖的?
spring是通过三级缓存取解决循环依赖的核心就是把实例化和初始化步骤进行分开,然后放入缓存中,供另一个对象调用.
一级缓存 : 用来保存实例化和初始化都完成的对象
二级缓存 ; 用来保存实例化完成,但是初始化未完成的对象
三级缓存 : 用来保存一个对象工厂,提供一个匿名内部类,用于创建二级缓存
举一个简单例子来说明一下;
A和B发生循环引用时,流程
1.A进行实例化后 ,去创建一个对象工厂,并放入三级缓存中
这里我们要理解一下这个对象工厂:
如果A被AOP代理,那么通过这个工厂获取到的就是A代理后的对象
如果A没有被AOP代理,那么这个工厂获取到的就是A的实例化对象
2.A进行属性注入时,去创建B
3.B进行实例化,然后进行属性注入,需要A,则从三级缓存中去拿到A的代理对象,并注入
然后会删除三级缓存中的A对象,将A对象放入到二级缓存中
4.B完成初始化后,将B放入一级缓存中
5.A从一级缓存中拿到B对象进行属性注入,直到完成后续操作,将A从二级缓存中删除,放入一级缓存中.循环依赖结束
从上面的步骤我们可以看到:解决循环依赖的前提条件是:
1.不能全是构造方法的循环依赖(因为实例化和初始化分不开)
2.必须是单例的(因为必须是同一个对象)
11.@Autowired和@Resource区别?
@Resource是java自己的注解,它有两个重要的属性,name和type,name解析为bean的名字
type解析为bean的类型
@Autowired是spring的注解通过type进行注入,不去匹配name
12.spring事务隔离级别?
READ_UNCOMMITTED:读未提交-->脏读
READ_COMMITTED:读已提交-->不可重复读
REPEATABLE_READ:可重复读-->幻读
SERIALIZABLE:串行化
13.spring事务传播行为?
==举例==
方法A、方法B【主语】
方法A去调用方法B
==REQUIRED(默认传播行为)==
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。 如果单独调用方法B时,没有事务,spring就给当前方法创建一个新事务 如果方法A中已经存在了事务,调用方法B时,方法B加方法A的事务中....
==SUPPORTS==
支持当前事务,如果当前没有事务,就以非事务方式执行 如果单独调用方法B时没有事务,咱们就以非事务方法运行 如果方法A中已经存在了事务,调用方法B时,方法B加方法A的事务中....
==MANDATORY==
使用当前的事务,如果当前没有事务,就抛出异常
==REQUERS_NEW==
新建事务,如果当前在事务中,把当前事务挂起
方法A调用方法B,如果方法A有事务 ,则挂起事务,为方法B开启新事务,执行完毕,方法A恢复事务。
这两个事务相互不影响,方法A回滚或提交,不会影响方法B反之一样。
==NOT_SUPPORTED==
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
==NEVER==
以非事务方式运行,如果当前存在事务,抛出异常
==NESTED==
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行 REQUIRED 类似的操作
14.SpringBoot自动装配原理?
通过EnableAutoConfiguration注解开启自动配置,通过@import注解会自动扫描到META-INF下面的spring.factories,然后会将这些配置类加载到容器中