1. IOC的理解(what why how)?
what
控制反转(
Inverse Of Control
)
不是什么技术,而是一种设计思想。它的目的是指导我们设计出更加松耦合的程序。
控制:在
java
中指的是对象的控制权限(创建、销毁)
反转:指的是对象控制权由原来
由开发者在类中手动控制
反转到
由
Spring
容器控制
Why
原本的代码是直接使用new的方式创建对象,导致的问题就是对象之间的依赖关系十分严重,耦合度非常高而且依赖关系都写死在了代码里,项目不易修改和维护,,一旦需要修改,就必须要改代码,违背了我们对扩展开放,对修改关闭的原则。但是使用spring中后就不一样了,我们在代码里面只需要声明我需要什么样的接口,由Spring帮助我们进行依赖注入,那么一旦我们需要更换实现类,那么只需要修改Spring的配置文件即可,不需要修改代码。
How
- BeanFactroy
- 采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常
- 采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常
- 流程
- 加载配置文件,解析成 BeanDefinition 放在 Map 里
- 调用 getBean 的时候,从 BeanDefinition 所属的 Map 里,拿出 Class 对象进行实例化,同时如果有依赖关系,将递归调用 getBean 方法 —— 完成依赖注入。
- ApplicationContext
- 它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。
- 相对于基本的BeanFactory,ApplicationContext 唯一的不足是
占用内存空间
。当应用程序配置Bean较多时,程序启动较慢
Spring如何解决循环依赖问题?
解释:多个bean之间相互依赖,形成了一个闭环。 比如:A依赖于B、B依赖于c、c依赖于A
Spring解决循环依赖是有前置条件
的
- 出现循环依赖的Bean必须要是
单例
(singleton),如果依赖prototype则完全不会有此需求。 - 依赖注入的方式
不能全是
构造器注入的方式(只能解决setter方法的循环依赖,这是错误的)
Spring通过三级缓存解决了循环依赖,其中一级缓存为单例池(singletonObjects),二级缓存为早期曝光对象earlySingletonObjects,三级缓存为早期曝光对象工厂(singletonFactories)
当A、B两个类发生循环引用时,在A完成实例化后,就使用实例化后的对象去创建一个对象工厂
,添加到三级缓存中,如果A被AOP代理,那么通过这个工厂获取到的就是A代理后
的对象,如果A没有被AOP代理,那么这个工厂获取到的就是A实例化的对象。
当A进行属性注入时,会去创建B,同时B又依赖了A,所以创建B的同时又会去调用getBean(a)来获取需要的依赖,此时的getBean(a)会从缓存中获取
2.AOP的理解
What
AOP
为
Aspect Oriented Programming
的缩写,意思为
面向切面编程
AOP
是
OOP
(面向对象编程) 的延续,是软件开发中的一个热点,也是
Spring
框架中的一个重要内
容,利用
AOP
可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高
程序的可重用性,同时提高了开发的效率。
Why
在程序运行期间,在不修改源码的情况下对方法进行功能增强
逻辑清晰,开发核心业务的时候,不必关注增强业务的代码
减少重复代码,提高开发效率,便于后期维护
How
实际上,
AOP
的底层是通过
Spring
提供的的
动态代理技术
实现的。在运行期间,
Spring
通过动态代
理技术动态的生成代理对象,代理对象方法执行时进行增强功能的介入,在去调用目标对象的方法,从
而完成功能的增强。