NO.5 Spring IOC 对象的实例化过程
这里,我们需要知道一个名词——DI(依赖注入)。
需要一个对象,就让工厂注入进去一个对象,需要一个service,就让IOC注入一个service。
IOC就是一个大工厂,专门用来生产对象的,将图纸 (Java的class文件)给工厂,工厂就能负责建造。将class文件(图纸)配置到spring的配置文件——应用的上下文applicationContext.xml,实现向工厂一扔,自动创建。那么bean是如何创建的呢?
在ApplicationContext之前,我们使用的是BeanFactory。
如图是ApplicationContext类的结构,紫色的均为接口,绿色的均为抽象类或接口的实现类
BeanFactory与ApplicationContext的相同和区别:
1>都是接口,用来定义规范,ApplicationContext也是继承于BeanFactory
2>BeanFactory定义了类产生的原始过程,ApplicationContext采用适用现代计算机产生bean的过程。
3>实例化过程不同
BeanFactory在加载bean,需要做出判断,当获取对象时才实例化对象(使用的时候才去实例化),优点:节省系统内存,缺点需要的时候才去生产,浪费时间(eg:手机中App)
ApplicationContext当容器初始化完成之后就实例化对象(工厂一旦创建成功,就有实例化对象),不管使用不使用,对象已经生产完成了,优点:性能好,缺点:容器初始化后即完成对象生产,占用内存(eg:电脑,服务器(8G标配))
那么我们如何验证对象是什么时间被生产出来的呢?
一个类被实例化,就要调用它的构造方法。
package com.xt.spring.ioc.ore;
public class Apple extends Fruit{
//构造方法,输出一个日志
public Apple(){
System.out.println("苹果已经生产出来了");
}
public void eat(){
System.out.println("我是苹果");
}
}
测试类:
package com.xt.spring.ioc.test;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.xt.spring.ioc.ore.Apple;
public class IOCTest {
private ApplicationContext ioc0;
//IOC容器与对象之间有一个过程
@Before
public void iocInit(){
ioc0 = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
//打印一个标记,苹果是否已经创建
System.out.println("不知道苹果是否创建出来??");
//如果已经被创建,则会打印构造方法中的日志
}
@Test
public void testIoc(){
//获取而非创建对象
Apple a0 = ioc0.getBean("apple",Apple.class);
a0.eat();
}
}
可以看到控制台打印出的日志,显然工厂在初始化完成之后就已经完成了对象的创建。
综上所知,我们可以总结IOC容器中对象的实例化过程:
1,IOC容器实例化
2,IOC实例化完成之后,立刻开始实例化IOC容器中配置的javabean
3,使用javabean
容器未创建之前,未创建java bean ,初始化完成之后,java bean 即被创建,在实例化之前