一. 什么是Spring Ioc思想?
Spring Ioc的目的就是通过一个容器来控制对象的生命周期以及对象之间的关系。所有的类都会在Spring容器中进行注册登记,由Spring Ioc容器来创建、控制运行和销毁。
1.1 Spring Ioc容器的基本构成
通过上面这段话,首先可以确立两个角色,一个是容器,一个是存在容器中的类。那么首先来分析Spring源码中这两个角色的代表对象是什么?
- 容器
Ioc 容器主要有两大实现:
- 1.BeanFactory为原始接口的基本容器实现
- 2.ApplicationContext为原始接口的高级容器实现
- 角色
所有注册登记在Ioc容器中的类,都统称为角色,由 Beandefinition 来表示
由于Spring要兼顾功能强大,以及扩展性好,上面的容器和角色的类都有很多实现类。
1.2 Bean的生命周期
上面所提到的角色,统称为Bean。要分析Ioc容器初始化以及运行过程,那么Bean是一个不可能忽略的角色。前面也提到了,Ioc的思想就是,有Ioc容器来管理所登记类的生命周期,即Bean的生命周期。
类相关的信息都在Ioc容器初始化的时候被解析成 BeanDefinition 对象的形式存在于容器中。但这个时候并不能使用,因为BeanDefinition并不是真正的类对象。
XmlBeanFactory factory = new XmlBeanFactory(res);
// 可以看出对象是由容器通过getBean方法得到的
User user = factory.getBean(User.class);
AbstractBeanFactory.getBean()
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
// 实际调用的doGetBean方法
return this.doGetBean(name, requiredType, args, false);
}
protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = this.transformedBeanName(name);
// 从三级缓存中获取,是否对象已经存在(后面会说到这个方法,用来解决循环依赖)
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
.....
// 如果缓存中有,说明要不就是提前暴露出来的
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
// 缓存中没有正在创建的单例bean
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//对IoC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否
//能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器
//的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
// 获取所有的依赖bean,即依赖是一个bean,那就先把依赖bean给创建了
String[] dependsOn = mbd.getDependsOn();
String[] var11;
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;
for(int var13 = 0; var13 < var12; ++var13) {
String dep = var11[var13];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
this.registerDependentBean(dep, beanName);
// 创建依赖的bean
this.getBean(dep);
}
}
// 这里会根据bean要求初始化类型的不同,而通过new ObjectFactory() 进行不同的处理。
// 一般都是单例,只关心这个。
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
// 实际是调用了createBean方法去创造bean
return AbstractBeanFactory.this.createBean(beanName, mbd, args);
} catch (BeansException var2) {
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 如果是多例
else if (mbd.isPrototype()) {
....
.....
}
Spring的源码太过于复杂了,来抓住主要点。通过上面的代码,我们可以得到三个点:
- 1.为了防止引用循环的产生,Spring会通过三级缓存来存储提前暴露但还没有初始化完成的bean。创造bean的时候先从这些缓存中获取。
- 2.检查BeanDefinition中的依赖信息,如果有相关依赖Bean,先创建依赖Bean
- 3.针对Bean定义的模式,采取的不同创建Bean实例对象的策略,具体的Bean实例对象的创建过程由实现了ObejctFactory接口的匿名内部类的createBean方法完成,ObejctFactory使用委派模式,具体的Bean实例创建过程交由其实现类AbstractAutowireCapableBeanFactory完成
继续来看:
//创建Bean实例对象
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
mbdToUse.prepareMethodOverrides();
}
Object beanInstance;
try {
// 这里是在创建bean实例前,进行
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var8);
}
// 创建Bean对象
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
//真正创建Bean的方法
36 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
//封装被创建的Bean对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()){//单态模式的Bean,先从容器中缓存中获取同名Bean
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//在这里创建还没有注入的属性的bean实例。
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
//获取bean对象的类型
Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
//调用PostProcessor后置处理器(这个BeanPostProcessor 实际上是InstantiationAwareBeanPostProcessorAdapter)
// 不同于一般的BeanPostProcessor实现类,一般的BeanPostProcessor类通常是在bean初始化前后进行切面。
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
//向容器中缓存单态模式的Bean对象,以防循环引用
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
......
//这里addSingletonFactory,就是为了解决循环引用,将还没有属性注入
//的bean对象,放入到 三级缓存中, 提前暴露出来
addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
Object exposedObject = bean;
try {
// 这个方法里面进行属性注入
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
//对实例化好的对象,进行初始化。
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
.....
if (earlySingletonExposure) {
//获取指定名称的已注册的单态模式Bean对象
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
//根据名称获取的以注册的Bean和正在实例化的Bean是同一个
if (exposedObject == bean) {
//当前实例化的Bean初始化完成
exposedObject = earlySingletonReference;
}
//当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
//获取当前Bean所依赖的其他Bean
for (String dependentBean : dependentBeans) {
//对依赖Bean进行类型检查
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
....
}
}
}
//注册完成依赖注入的Bean
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
太复杂了!!!
上面的代码就是getBean()的全部流程,同样抓住重点:
- 1.通过代理创建之前,会调用所有继承了 InstantiationAwareBeanPostProcessorAdapter 类,执行其中的前置方法。
// 在createBean()方法中这一行代码resolveBeforeInstantiation()方法内进行
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
- 2.创建一个没有属性注入的Bean对象
// 在doCreatBean()方法中,实际里面是通过动态代理的方式,创建对象的
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
- 3.没有属性注入的对象创建之后,不急着属性注入,先会调用所有继承了 InstantiationAwareBeanPostProcessorAdapter 类,执行其中的后置方法。
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
// 这个方法里进行后置调用
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
- 4.在属性注入以前,还要做一件事,把Bean对象放入三级缓存中,使得
不会发生循环引用。
if (earlySingletonExposure) {
......
//这里addSingletonFactory,就是为了解决循环引用,将还没有属性注入
//的bean对象,放入到 三级缓存中, 提前暴露出来
addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// 同时,在获取bean的时候,会通过AbstractBeanFactory中的 doGetBean() 中的
Object sharedInstance = this.getSingleton(beanName);
// 先尝试从缓存中获取,
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 先尝试从一级缓存中获取。
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
Map var4 = this.singletonObjects;
synchronized(this.singletonObjects) {
// 再尝试从二级缓存中获取。
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject != NULL_OBJECT ? singletonObject : null;
}
- 5.属性注入
// 这里面进行属性注入。
this.populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 这个方法中,对属性注入后的Bean进行初始化,
//在初始化前后分别有BeanPostProcessor 的前置方法和后置方法调用。
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}
最后用一张图来表示Bean的生命周期。