IOC原理

Bean对象的创建周期
xxx.class -> 推断构造方法 -> 对象(其属性还未赋值) -> 依赖注入(Autowred) -> 初始化前 -> 初始化(aterPropertiesSet) -> 初始化后(AOP) -> (代理对象) -> 存入Map -> Bean对象

  • 单例池:存放所有单例Bean的缓存池。可能存在不同名,但同类型的Bean。
  • 推断构造方法:有@Autowired优先,无参优先;有多个有参构造但没有无参,报错
  • 查找策略:先根据类型,再根据 名字从单例池中查找。
  • 命名:如果Compoent没有显式命名,Spring会默认用小写类名去命名。

类、类实例、类的Class对象、类加载器

  • .java文件经过javac.exe编译为.class二进制文件。一般存放在和.java源文件位置相似的地方。
  • 类的Class对象用来描述一个类,每个类都对应一个Class对象,包含了类的元信息,如类的名称、父类、实现的接口、类的修饰符等。通过Class对象可以创造一个该类的实例。
  • 类加载器classLoader的主要作用就是加载 Java 类的字节码( .class 文件)到 JVM 中(在内存中生成一个代表该类的 Class 对象)。
  • 可以通过上图中的getClass()以及getClassLoader()方法进行转换。

手写一个IOC Demo

  • 理解@ComponentScan、@Component、@Scope、@Autowired

循环依赖

按照之前Bean的生命周期,构造实例化 -> 依赖注入 -> 存入单例池。那么如果类中的属性相互依赖对方,导致创建Bean之后进行依赖注入时,发现需要注入的类也在等待自己。因此双方都在等待,无法完成创建。Spring是如何解决的?如果按照一般思路:可以先将双方进行实例化,延迟依赖注入。

1
2
3
4
5
6
7
8
9
10
11
12
@Component  
public class OneService {

@Autowired
private TwoService twoService;
}

@Component
public class TwoService {
@Autowired
private OneService oneService;
}

三级缓存机制

  1. 第一级:singletonObjects:存储最终的单例
  2. 第二级:earlySingletonObjects:存放发生循环依赖时的,并提前AOP的中间态Bean。防止发生多个循环依赖时,创建多个中间态Bean。(中间态指因循环依赖而未完成全部构造过程的Bean)
  3. 第三级:singletonFactories:用来存放提前AOP时的对象表达式(先于AOP,二级缓存存的是AOP后的)
    提前AOP

AOP原理

xxxProxy对象 -> xxx代理对象 -> xxx代理对象.target = 普通对象(被代理的原对象)-> 放入单例池