您的位置:首页 > 编程语言 > Java开发

Spring源码阅读(三)—IOC容器依赖注入

2017-08-30 13:51 886 查看

Spring源码阅读(三)—IOC容器依赖注入

IOC容器的初始化(Bean载入)和容器依赖注入是两个相对独立的过程.依赖注入一般发生在应用第一个通过getBean()方法向容器索取Bean的时候.

可以通过设置Bean的lazyinit属性实现Bean的预实例化,将这个Bean的依赖注入在在IOC容器初始化时候就完成.

个人主页:tuzhenyu’s page

原文地址:Spring源码阅读(三)—IOC容器依赖注入

(一) IOC容器依赖注入入口

从加载好的BeanFactory工厂中调用getBean()方法加载Bean,该方法会触发容器的依赖注入.

HelloBoy helloBoy = (HelloBoy)factory.getBean("boy");
helloBoy.sayHello();


(二) Bean的加载

getBean()方法的调用会触发AbstractBeanFactory的doGetBean()方法,该方法主要包括以下几部:

尝试从缓存中取Bean

如果缓存中不存在则创建Bean

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);
//从缓存中读取Bean
Object bean;
if(sharedInstance != null && args == null) {
//如果缓存中存在该Bean,则从缓存中加载该Bean
if(this.logger.isDebugEnabled()) {
if(this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.debug("Returning eagerly cached instance of singleton bean \'" + beanName + "\' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.debug("Returning cached instance of singleton bean \'" + beanName + "\'");
}
}

bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
//如果缓存中不存在该Bean,则创建该Bean
if(this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}

BeanFactory ex = this.getParentBeanFactory();
if(ex != null && !this.containsBeanDefinition(beanName)) {
String var24 = this.originalBeanName(name);
if(args != null) {
return ex.getBean(var24, args);
}

return ex.getBean(var24, requiredType);
}

if(!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}

try {
final RootBeanDefinition ex1 = this.get
1311a
MergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(ex1, beanName, args);
String[] dependsOn = ex1.getDependsOn();
String[] scopeName;
if(dependsOn != null) {
scopeName = dependsOn;
int scope = dependsOn.length;

for(int ex2 = 0; ex2 < scope; ++ex2) {
String dependsOnBean = scopeName[ex2];
if(this.isDependent(beanName, dependsOnBean)) {
throw new BeanCreationException(ex1.getResourceDescription(), beanName, "Circular depends-on relationship between \'" + beanName + "\' and \'" + dependsOnBean + "\'");
}

this.registerDependentBean(dependsOnBean, beanName);
this.getBean(dependsOnBean);
}
}

if(ex1.isSingleton()) {
sharedInstance = this.getSingleton(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
try {
return AbstractBeanFactory.this.createBean(beanName, ex1, args);
} catch (BeansException var2) {
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, ex1);
} else if(ex1.isPrototype()) {
scopeName = null;

Object var25;
try {
this.beforePrototypeCreation(beanName);
var25 = this.createBean(beanName, ex1, args);
} finally {
this.afterPrototypeCreation(beanName);
}

bean = this.getObjectForBeanInstance(var25, name, beanName, ex1);
} else {
String var26 = ex1.getScope();
Scope var27 = (Scope)this.scopes.get(var26);
if(var27 == null) {
throw new IllegalStateException("No Scope registered for scope \'" + var26 + "\'");
}

try {
Object var28 = var27.get(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
AbstractBeanFactory.this.beforePrototypeCreation(beanName);

Object var1;
try {
var1 = AbstractBeanFactory.this.createBean(beanName, ex1, args);
} finally {
AbstractBeanFactory.this.afterPrototypeCreation(beanName);
}

return var1;
}
});
bean = this.getObjectForBeanInstance(var28, name, beanName, ex1);
} catch (IllegalStateException var21) {
throw new BeanCreationException(beanName, "Scope \'" + var26 + "\' is not active for the current thread; " + "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var21);
}
}
} catch (BeansException var23) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var23;
}
}

if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return this.getTypeConverter().convertIfNecessary(bean, requiredType);
} catch (TypeMismatchException var22) {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Failed to convert bean \'" + name + "\' to required type [" + ClassUtils.getQualifiedName(requiredType) + "]", var22);
}

throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}


(三) 从缓存中加载Bean

单例Bean在Spring的同一个容器中只会被创建一次,后续再获取bean都会直接从单例缓存中获取.单例缓存在DefaultSingletonBeanRegistry类的一个map型数据结构singletonObjects中.从缓存中取Bean时候如果singletonObjects缓存中存在则直接返回相应的Bean.

如果缓存中不存在且通过isSingletonCurrentlyInCreation()方法知道该bean正在被创建则从earlySingletonObjects尝试获取

如果earlySingletonObjects不存在则获取ObjectFactory类型的singletonFactory工厂,从singletonFactory中利用getObject()方法获取singleObject并将其放入earlySingletonObjects中,移除singletonFactories中的工厂singletonFactory.

earlySingletonObjects和singletonObjects都是用来保存beanName和bean实例之间的关系,与singletonObjects不同之处在于,当一个bean被放在这里面之后,当bean还在创建过程中,就可以通过getBean方法获取到,其目的是用来检测循环引用.

public Object getSingleton(String beanName) {
return this.getSingleton(beanName, true);
}

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;
}


(四) 从Bean中获取对象

如果缓存中存在该bean,则可以直接取出.取出后可以通过getObjectForBeanInstance()方法从bean中获取对象.

如果指定的name是工程相关的(以&开头)并且beanInstance不是FactoryBean类则验证不通过直接抛出错误.

如果指定的name不是工程相关的(以&开头)并且beanInstance是FactoryBean类则从FactoryBean中解析出对象

除了以上两种情况,直接返回beanInstance作为对象.

protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
if(BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(this.transformedBeanName(name), beanInstance.getClass());
} else if(beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
Object object = null;
if(mbd == null) {
object = this.getCachedObjectForFactoryBean(beanName);
}

if(object == null) {
FactoryBean factory = (FactoryBean)beanInstance;
if(mbd == null && this.containsBeanDefinition(beanName)) {
mbd = this.getMergedLocalBeanDefinition(beanName);
}

boolean synthetic = mbd != null && mbd.isSynthetic();
object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
}

return object;
} else {
return beanInstance;
}
}


确认为FactoryBean确认完成后将从Factory中解析出bean对象的工作委托给getObjectFromFactoryBean()方法

getObjectFromFactoryBean()方法先查看缓存中是否存在该bean对象,如果不存在则委托给doGetObjectFromFactoryBean从FactoryBean中解析出bean对象.

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if(factory.isSingleton() && this.containsSingleton(beanName)) {
synchronized(this.getSingletonMutex()) {
Object ex = this.factoryBeanObjectCache.get(beanName);
if(ex == null) {
ex = this.doGetObjectFromFactoryBean(factory, beanName);
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if(alreadyThere != null) {
ex = alreadyThere;
} else {
if(ex != null && shouldPostProcess) {
try {
ex = this.postProcessObjectFromFactoryBean(ex, beanName);
} catch (Throwable var9) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean\'s singleton object failed", var9);
}
}

this.factoryBeanObjectCache.put(beanName, ex != null?ex:NULL_OBJECT);
}
}

return ex != NULL_OBJECT?ex:null;
}
} else {
Object object = this.doGetObjectFromFactoryBean(factory, beanName);
if(object != null && shouldPostProcess) {
try {
object = this.postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable var11) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean\'s object failed", var11);
}
}

return object;
}
}


doGetObjectFromFactoryBean方法调用factory.getObject()方法获得bean对象

private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try {
if(System.getSecurityManager() != null) {
AccessControlContext ex = this.getAccessControlContext();

try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws Exception {
return factory.getObject();
}
}, ex);
} catch (PrivilegedActionException var6) {
throw var6.getException();
}
} else {
object = factory.getObject();
}
} catch (FactoryBeanNotInitializedException var7) {
throw new BeanCurrentlyInCreationException(beanName, var7.toString());
} catch (Throwable var8) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", var8);
}

if(object == null && this.isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");
} else {
return object;
}
}


(五) 创建Bean

从生成的ObjectFactory中获取bean

如果缓存中不存在已经加载的单例bean,就需要从头开始加载,Spring中通过getSingleton()的重载方法实现bean的加载过程.重载方法传入ObjectFactory参数,在getSingleton中调用objectFactory.getOBject()方法获取bean对象.getSingleton()主要操作内容包括:

在beforeSingletonCreation()方法调用中将beanName加入singletonCurrentlyInCreation标记中,其他bean加载依赖时候如果发现该bean在singletonCurrentlyInCreation标记中则获取ObjectFactory放入earlySingletonObjects中.

通过调用参数传入的ObjectFactory的getObject()方法实例化bean对象,在getObject()方法中会调用createBean()方法实例化bean.

在afterSingletonCreation()方法调用中将beanName从singletonCurrentlyInCreation标记中去除

将结果记录到bean缓存singletonObjects中,并删除加载bean过程中的所记录的各种辅助状态earlySingletonObjects,singletonFactories等.

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "\'beanName\' must not be null");
Map var3 = this.singletonObjects;
synchronized(this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if(singletonObject == null) {
if(this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while the singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");
}

if(this.logger.isDebugEnabled()) {
this.logger.debug("Creating shared instance of singleton bean \'" + beanName + "\'");
}

this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if(recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}

try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException var16) {
singletonObject = this.singletonObjects.get(beanName);
if(singletonObject == null) {
throw var16;
}
} catch (BeanCreationException var17) {
BeanCreationException ex = var17;
if(recordSuppressedExceptions) {
Iterator var8 = this.suppressedExceptions.iterator();

while(var8.hasNext()) {
Exception suppressedException = (Exception)var8.next();
ex.addRelatedCause(suppressedException);
}
}

throw ex;
} finally {
if(recordSuppressedExceptions) {
this.suppressedExceptions = null;
}

this.afterSingletonCreation(beanName);
}

if(newSingleton) {
this.addSingleton(beanName, singletonObject);
}
}

return singletonObject != NULL_OBJECT?singletonObject:null;
}
}


生成的ObjectFactory,准备创建bean

在ObjectFactory的getObject()方法中调用createBean()方法,用来创建bean

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Creating instance of bean \'" + beanName + "\'");
}

this.resolveBeanClass(mbd, beanName, new Class[0]);

try {
mbd.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var5) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", var5);
}

Object beanInstance;
try {
beanInstance = this.resolveBeforeInstantiation(beanName, mbd);
if(beanInstance != null) {
return beanInstance;
}
} catch (Throwable var6) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var6);
}

beanInstance = this.doCreateBean(beanName, mbd, args);
if(this.logger.isDebugEnabled()) {
this.logger.debug("Finished creating instance of bean \'" + beanName + "\'");
}

return beanInstance;
}


createBean()方法通过调用doCreateBean()方法真正创建bean

调用createBeanInstance()方法调用构造方法构造原始对象(未进行属性装载),将BeanDefinition转换为bean;

判断是否需要提前曝光,如果需要则调用addSingleFactory()方法将原始bean的工厂添加到singletonFactories中.

调用populateBean()方法对原始bean进行属性填充,如果依赖其他bean则会递归调用getBean()方法.

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) {
BeanWrapper instanceWrapper = null;
if(mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}

if(instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}

final Object bean = instanceWrapper != null?instanceWrapper.getWrappedInstance():null;
Class beanType = instanceWrapper != null?instanceWrapper.getWrappedClass():null;
Object earlySingletonExposure = mbd.postProcessingLock;
synchronized(mbd.postProcessingLock) {
if(!mbd.postProcessed) {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}

boolean var19 = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if(var19) {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Eagerly caching bean \'" + beanName + "\' to allow for resolving potential circular references");
}

this.addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
}
});
}

Object exposedObject = bean;

try {
this.populateBean(beanName, mbd, instanceWrapper);
if(exposedObject != null) {
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}
} catch (Throwable var17) {
if(var17 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var17).getBeanName())) {
throw (BeanCreationException)var17;
}

throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var17);
}

if(var19) {
Object ex = this.getSingleton(beanName, false);
if(ex != null) {
if(exposedObject == bean) {
exposedObject = ex;
} else if(!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
LinkedHashSet actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length;

for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
if(!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}

if(!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName, "Bean with name \'" + beanName + "\' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "\'getBeanNamesOfType\' with the \'allowEagerInit\' flag turned off, for example.");
}
}
}
}

try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}


(六) 总结

IOC容器的初始化和容器的依赖注入是两个相对独立的过程,在容器初始化时不会进行依赖的注入.而是当调用getBean()方法获取bean实例的时候会进行依赖注入.

bean实例的获取分为两种形式:从缓存中获取和从头创建获取.

(1) 缓存中获取

为了解决单例模式的循环依赖问题,spring采用三级缓存:singletonFactories,earlySingletonObjets,singletonObjects

先尝试从singletonObjects中取出bean对应的singleObject,如果加载不成功则通过isSingletonCurrentlyInCreation标志位判断是否该bean正在被创建.如果正在被创建则为了解决循环依赖尝试从二级缓存earlySingletonObjects中取,如果一级缓存singletonObjects中没有该bean并且也没有正在被创建,则从头创建该bean.

尝试从二级缓存earlySingletonObjects中加载该bean对应的singletonObject,如果加载失败则尝试从三级缓存singletonFactories中加载singletonObject对应的工程singletonFactory,并调用getObject()方法获取singletonObject放入二级缓存earlySingletonObjets中,并删除三级缓存singletonFactories中的相应缓存.

从bean实例singletonObject中调用getObjectForBeanInstance()方法获取对象,判断是否为FactoryBean类型,如果是则调用getObject()方法获取对象.

(2) 从头创建

从头创建Bean的方法入口在重载的getSingletion(),包含工厂类参数ObjectFactory从中调用getObject获取bean实例.

getSingletion()方法首先调用beforeSingletonCreation()方法,在该方法中添加该bean的isSingletonCurrentlyInCreation标志位

接着调用getObject()方法获取bean实例,getObject()方法中包含bean创建的方法入口createBean()方法.

createBean()方法调用doCreateBean()方法真正创建bean

首先调用createBeanInstance()方法,就是调用对应的构造方法构造对象,此时只是调用了构造方法创建出的最原始的bean实例,如果在构造器创建原始bean的过程中出现循环依赖则会抛出循环依赖错误.

判断时候需要提前曝光(单例&允许循环依赖&存在isSingletonCurrentlyInCreation标志位),如果需要则调用addSingletonFactory()方法将构造器创建原始bean实例封装后放入三级缓存singletonFactories中.

调用populateBean()方法对原始bean进行属性填充

完成创建并返回bean实例

接着调用afterSingletonCreation()方法删除该bean的isSingletonCurrentlyInCreation标志位

最后调用addSingleton()方法将获取的bean实例放入一级缓存singtonObjects,并从二级缓存earlySingletonObjets和三级缓存singletonFactories中删除对应的bean.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: