如果IoC容器已经载入了用户定义的Bean信息,并开始分析依赖注入的原理。依赖注入是用户第一次向IoC容器索要Bean时触发的,当然也有例外。如果我们设置了lazy-init的属性。是可以在刚开始初始化容器的时候就为我们生成新的bean。
首先我们从DefaultListableBeanFactory类中来查看getBean触发的依赖注入
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(String, Class<T>, Object[], boolean)
getBean方法里面都调用了doGetBean这个方法
由于这个方法非常非常长,所以我就不再粘贴出来。而是从这个方法里面找寻一些有用的信息。
doGetBean是一个很漫长的过程。而且根据我们创建的bean的要求不同,会有不同的创建方法。
首先我们要去缓存中去取,处理已经被创建过的单例模式的bean,对这种bean的请求不需要重复创建。
关于这样一行代码,是FactoryBean对于我们的实体bean的一个修饰作用
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
接下里就是对BeanDefinition在IoC容器的查找存在,如果当前的IoC容器不存在那么就要去它的父类进行查找。如果最后没有查找结果。
取得bean以及这个bean所依赖的所有bean之后,我们就需要根据bean的创建要求来进行生成bean。
一种是Singleton bean,一种是prototype bean(这种bean每一次请求都会有一个新的对象产生)
最后我们要对创建出来的bean进行类型检查,如果没有问题,就把我们创建出来的bean返回。
现在我们主要来看看依赖注入的关键步骤,怎样根据BeanDefinition来生成对应的bean。接下来要进入到createBean中来具体进行说明。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
具体的我们进入到createBean中来查看
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(String, RootBeanDefinition, Object[])
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
首先我们创建一个BeanWrapper来斥候我们的bean对象,如果是singleton,先把缓存中的同名bean清除。
具体的创建交给createBeanInstance来完成
之后就是对bean的初始化,依赖注入。这个主要是交给populateBean()方法来完成.
当实例化bean对象生成的基础上,spring需要对这些对象进行处理,各种bean对象生成以后,怎样把这些bean对象的依赖关系设置好,完成整个依赖注入的过程。这里涉及对各种对象Bean的属性的处理过程。
依赖注入过程,先处理autowire注入 。之后对属性的具体注入是在
applyPropertyValues(beanName, mbd, bw, pvs);
中完成的
现在进入到applyPropertyValues中去看看具体的对属性进行解析然后注入的过程
首先我们获取到了这个bean所需要的所有属性
if (pvs == null || pvs.isEmpty()) {
return;
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (System.getSecurityManager() != null) {
if (bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
}
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
}
然后我们对我们的这个original链表进行一次拷贝。
之后我们需要获取一系列的转换器用来将我们的BeanDefinition内的数据以及生成的bean对象进行依赖注入
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
之后是关于bean的属性的解析和注入,可以从书上进行查看相关的源码。