IoC依赖注入
对于IoC容器初始化的过程已经完成了,初始化就是在容器中建立BeanDefinition的数据映射,接下来我们来分析下,Spring是怎么对Bean进行依赖注入的
Bean的初始化一般是在第一次获取这个Bean的时候完成的,也可以设置lazy-init完成预实例化,现在我来看第一次获取时,是怎么样依赖注入的:
依赖注入的开始就是在BeanFactory里面就有的一个方法,getBean().我们来看他在AbstractFactory中是怎么实现的
1.依赖注入的开始,getBean
public Object getBean(String name) throws BeansException {
return getBean(name, null, null);
}
public Object getBean(String name, Class requiredType, Object[] args) throws BeansException {
return doGetBean(name, requiredType, args, false);
}
protected Object doGetBean(
final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
//转化name,如果是BeanName就返回BeanName,如果是别名,就从Map中找出对应BeanName返回
final String beanName = transformedBeanName(name);
Object bean = null;
// Eagerly check singleton cache for manually registered singletons.
//查看缓存中是否有这个实例
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//处理这个Bean
//如果这是一个普通bean 直接去创建FactoryBean,如果是FactoryBean,直接返回
//有可能这个实例是返回的父BeanFactory 缓存里面的Bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
//检查BeanDefinition是否在Factory中 ,如果找不到就一直找父factory
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
//根据name获取BeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
//依次加载依靠的BeanDefinition
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (int i = 0; i < dependsOn.length; i++) {
String dependsOnBean = dependsOn[i];
getBean(dependsOnBean);
registerDependentBean(dependsOnBean, beanName);
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final Scope scope = (Scope) this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' 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",
ex);
}
}
}
//检查是否符合类型,这个Bean已经包含依赖关系
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return bean;
}
调用里面的createBean这个方法,按照BeanDefinition里面的信息,返回这个Instance
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
AccessControlContext acc = AccessController.getContext();
return AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
// Make sure bean class is actually resolved at this point.
//判定是否可以实例化,是否可以通过加载器实现
resolveBeanClass(mbd, beanName);
// Prepare method overrides.
try {
//
mbd.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//如果配置了BeanPostProcessors,返回一个代理
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
//创建实例
Object beanInstance = doCreateBean(beanName, mbd, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
}, acc);
}
doCreateBean方法,这里创建Bean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// Instantiate the bean.
//BeanWrapper是用来持有新创建的Bean的
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName);
}
//由CreateBeanInstance方法创建Bean
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
//这里要对Bean进行初始化,依赖注入在此发生
// Initialize the bean instance.
Object exposedObject = bean;
try {
//初始化
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);
for (int i = 0; i < dependentBeans.length; i++) {
String dependentBean = dependentBeans[i];
if (!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.");
}
}
}
}
// Register bean as disposable.
registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
}
createBeanInstance方法创建了实例
这里有很多种不同的生成方法,如工厂方法,容器autowirs特性等.
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// Make sure bean class is actually resolved at this point.
//将BeanName转化为ClassName
Class beanClass = resolveBeanClass(mbd, beanName);
//使用工厂方法对Bean进行实例化
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
if (mbd.resolvedConstructorOrFactoryMethod != null) {
if (mbd.constructorArgumentsResolved) {
return autowireConstructor(beanName, mbd, null, args);
}
else {
//最常见的生成实例的方法,使用cglib
return instantiateBean(beanName, mbd);
}
}
//使用构造函数实例化
// Need to determine the constructor...
Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//使用构造函数完成实例化
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
//使用默认的构造函数实例化
return instantiateBean(beanName, mbd);
}
下面我们看一个如何使用构造函数完成实例化
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, Constructor[] chosenCtors, Object[] explicitArgs) {
//
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor constructorToUse = null;
Object[] argsToUse = null;
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
constructorToUse = (Constructor) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
Class[] paramTypes = constructorToUse.getParameterTypes();
Object[] argsToResolve = mbd.preparedConstructorArguments;
TypeConverter converter = (this.typeConverter != null ? this.typeConverter : bw);
BeanDefinitionValueResolver valueResolver =
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
argsToUse = new Object[argsToResolve.length];
for (int i = 0; i < argsToResolve.length; i++) {
Object argValue = argsToResolve[i];
MethodParameter methodParam = new MethodParameter(constructorToUse, i);
if (JdkVersion.isAtLeastJava15()) {
GenericTypeResolver.resolveParameterType(methodParam, constructorToUse.getDeclaringClass());
}
if (argValue instanceof AutowiredArgumentMarker) {
argValue = resolveAutowiredArgument(methodParam, beanName, null, converter);
}
else if (argValue instanceof BeanMetadataElement) {
argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue);
}
argsToUse[i] = converter.convertIfNecessary(argValue, paramTypes[i], methodParam);
}
}
}
}
if (constructorToUse == null) {
// Need to resolve the constructor.
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs = 0;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// Take specified constructors, if any.
Constructor[] candidates =
(chosenCtors != null ? chosenCtors : mbd.getBeanClass().getDeclaredConstructors());
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
for (int i = 0; i < candidates.length; i++) {
Constructor candidate = candidates[i];
Class[] paramTypes = candidate.getParameterTypes();
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
if (paramTypes.length < minNrOfArgs) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
minNrOfArgs + " constructor arguments specified but no matching constructor found in bean '" +
beanName + "' " +
"(hint: specify index and/or type arguments for simple parameters to avoid type ambiguities)");
}
ArgumentsHolder args = null;
List causes = null;
if (resolvedValues != null) {
// Try to resolve arguments for current constructor.
try {
args = createArgumentArray(
beanName, mbd, resolvedValues, bw, paramTypes, candidate, autowiring);
}
catch (UnsatisfiedDependencyException ex) {
if (this.beanFactory.logger.isTraceEnabled()) {
this.beanFactory.logger.trace(
"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
if (i == candidates.length - 1 && constructorToUse == null) {
if (causes != null) {
for (Iterator it = causes.iterator(); it.hasNext();) {
this.beanFactory.onSuppressedException((Exception) it.next());
}
}
throw ex;
}
else {
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList();
}
causes.add(ex);
continue;
}
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
args = new ArgumentsHolder(explicitArgs);
}
int typeDiffWeight = args.getTypeDifferenceWeight(paramTypes);
// Choose this constructor if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsToUse = args.arguments;
minTypeDiffWeight = typeDiffWeight;
}
}
if (constructorToUse == null) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Could not resolve matching constructor");
}
if (explicitArgs == null) {
mbd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
}
try {
Object beanInstance = this.instantiationStrategy.instantiate(
mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
bw.setWrappedInstance(beanInstance);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
下面是比较常用的,使用createBeanInstance来创建,cglib代理的对象
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
//使用cglib来进行实例化
Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
public Object instantiate(
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (beanDefinition.getMethodOverrides().isEmpty()) {
Constructor constructorToUse = (Constructor) beanDefinition.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
Class clazz = beanDefinition.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Exception ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
return BeanUtils.instantiateClass(constructorToUse, null);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(beanDefinition, beanName, owner);
}
}
没有找到怎么用cglib创建.
BeanUtils.instantiateClass(constructorToUse, null)是用java的反射实现的
======================================================================================
2.依赖注入的的准备工作:处理对象,设置依赖关系
现在我们已经分析完了实例化的整个过程,接下来就是处理这些对象,设置好依赖关系完成整个依赖注入的过程.
protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {
//获取property值,
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
//调用后置处理器
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
//判定是否继续处理property
if (!continueWithPropertyPopulation) {
return;
}
//进行依赖注入的过程,先处理autowire,有ByName和ByType两种类型
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//通过name自动装填
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
//通过type自动装填
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//检查容器是否持有用于处理单态模式Bean关闭时的后置处理器
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//检查是否有继承的类,即是否有依赖
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
//从实例对象中提取属性描述符
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw);
if (hasInstAwareBpps) {
for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext(); ) {
BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor;
//使用后置处理器处理
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//对具体参数进行注入
applyPropertyValues(beanName, mbd, bw, pvs);
}
我们继续分析生成对象后, Spring IoC 容器是如何将 Bean 的属性依赖关系注入 Bean 实例对象中并设置好的,属性依赖注入的代码如下:
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs == null || pvs.isEmpty()) {
return;
}
//封装属性值
MutablePropertyValues mpvs = null;
//所有属性对象的list
List original = null;
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());
}
//是否设置类型转换器了,没设置的话使用BeanWrapper
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//Bean属性值解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
//为解析值创建一个副本,
// Create a deep copy, resolving any references for values.
List deepCopy = new ArrayList(original.size());
boolean resolveNecessary = false;
for (Iterator it = original.iterator(); it.hasNext();) {
PropertyValue pv = (PropertyValue) it.next();
//不需要转化是属性值
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 = !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);
}//是string类型的值,并且可以转换
else if (originalValue instanceof TypedStringValue && convertible) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
重新封装属性的值
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
//标记属性值已经转换过
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
//进行依赖注入,在BeanWrapper中实现
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
下面是转换属性值的过程.如将引用转化为实例对象
//检查value的类型,如果是对象的引用转化为对象的实例
public Object resolveValueIfNecessary(Object argName, Object value) {
// We must check each value to see whether it requires a runtime reference
// to another bean to be resolved.
//将对象的引用转化为实例
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
return resolveReference(argName, ref);
}//属性值是引用容器中另一个Bean名称
else if (value instanceof RuntimeBeanNameReference) {
String ref = ((RuntimeBeanNameReference) value).getBeanName();
if (!this.beanFactory.containsBean(ref)) {
throw new BeanDefinitionStoreException(
"Invalid bean name '" + ref + "' in bean reference for " + argName);
}
return ref;
}//属性值是Bean类型的解析,主要是Bean中的内部类
else if (value instanceof BeanDefinitionHolder) {
// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
}
//
else if (value instanceof BeanDefinition) {
// Resolve plain BeanDefinition, without contained name: use dummy name.
BeanDefinition bd = (BeanDefinition) value;
return resolveInnerBean(argName, "(inner bean)", bd);
}//解析List,封装成Set<resolveValueIfNecessary>
else if (value instanceof ManagedList) {
// May need to resolve contained runtime references.
return resolveManagedList(argName, (List) value);
}//Set
else if (value instanceof ManagedSet) {
// May need to resolve contained runtime references.
return resolveManagedSet(argName, (Set) value);
}//Map
else if (value instanceof ManagedMap) {
// May need to resolve contained runtime references.
return resolveManagedMap(argName, (Map) value);
}// //解析props类型的属性值,props其实就是key和value均为字符串的map
else if (value instanceof ManagedProperties) {
Properties original = (Properties) value;
Properties copy = new Properties();
for (Iterator it = original.entrySet().iterator(); it.hasNext();) {
Map.Entry propEntry = (Map.Entry) it.next();
Object propKey = propEntry.getKey();
Object propValue = propEntry.getValue();
if (propKey instanceof TypedStringValue) {
propKey = ((TypedStringValue) propKey).getValue();
}
if (propValue instanceof TypedStringValue) {
propValue = ((TypedStringValue) propValue).getValue();
}
copy.put(propKey, propValue);
}
return copy;
}//如果值是String类型的,
else if (value instanceof TypedStringValue) {
// Convert value to target type here.
TypedStringValue typedStringValue = (TypedStringValue) value;
try {
Class resolvedTargetType = resolveTargetType(typedStringValue);
if (resolvedTargetType != null) {
return this.typeConverter.convertIfNecessary(typedStringValue.getValue(), resolvedTargetType);
}
else {
// No target type specified - no conversion necessary...
return typedStringValue.getValue();
}
}
catch (Throwable ex) {
// Improve the message by showing the context.
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Error converting typed String value for " + argName, ex);
}
}
else {
// No need to resolve value...
return value;
}
}
将对象引用转化为对象实例的过程如下
//将一个引用转化为一个实例
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
//如果这个实例在父BeanFactory中的话,在父类中获取
//递归调用加载Bean的过程
if (ref.isToParent()) {
if (this.beanFactory.getParentBeanFactory() == null) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Can't resolve reference to bean '" + ref.getBeanName() +
"' in parent factory: no parent factory available");
}
return this.beanFactory.getParentBeanFactory().getBean(ref.getBeanName());
}
else {
Object bean = this.beanFactory.getBean(ref.getBeanName());
this.beanFactory.registerDependentBean(ref.getBeanName(), this.beanName);
return bean;
}
}
catch (BeansException ex) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
}
}
3.依赖注入开始
完成这个解析过程后,已经为依赖注入做好了准备, //实现属性依赖注入功能
public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
throws BeansException {
List propertyAccessExceptions = null;
List propertyValues = (pvs instanceof MutablePropertyValues ?
((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
//
for (Iterator it = propertyValues.iterator(); it.hasNext();) {
PropertyValue pv = (PropertyValue) it.next();
try {
// This method may throw any BeansException, which won't be caught
// here, if there is a critical failure such as no matching field.
// We can attempt to deal only with less serious exceptions.
//依赖注入每个属性
setPropertyValue(pv);
}
catch (NotWritablePropertyException ex) {
if (!ignoreUnknown) {
throw ex;
}
// Otherwise, just ignore it and continue...
}
catch (NullValueInNestedPathException ex) {
if (!ignoreInvalid) {
throw ex;
}
// Otherwise, just ignore it and continue...
}
catch (PropertyAccessException ex) {
if (propertyAccessExceptions == null) {
propertyAccessExceptions = new LinkedList();
}
propertyAccessExceptions.add(ex);
}
}
// If we encountered individual exceptions, throw the composite exception.
if (propertyAccessExceptions != null) {
PropertyAccessException[] paeArray = (PropertyAccessException[])
propertyAccessExceptions.toArray(new PropertyAccessException[propertyAccessExceptions.size()]);
throw new PropertyBatchUpdateException(paeArray);
}
}
继续调用下面的方法
//在BeanWrapperImpl中实现了这个方法
public void setPropertyValue(PropertyValue pv) throws BeansException {
PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
if (tokens == null) {
String propertyName = pv.getName();
BeanWrapperImpl nestedBw = null;
try {
nestedBw = getBeanWrapperForPropertyPath(propertyName);
}
catch (NotReadablePropertyException ex) {
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
"Nested property in path '" + propertyName + "' does not exist", ex);
}
tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));
if (nestedBw == this) {
pv.getOriginalPropertyValue().resolvedTokens = tokens;
}
nestedBw.setPropertyValue(tokens, pv);
}
else {
setPropertyValue(tokens, pv);
}
}
实现属性依赖注入
//依赖注解的具体实现
private void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
//PropertyTokenHolder主要保存属性的名称、路径,以及集合的size等信息
String propertyName = tokens.canonicalName;
String actualName = tokens.actualName;
//keys是用来保存集合类型属性的size
if (tokens.keys != null) {
// Apply indexes and map keys: fetch value for all keys but the last one.
//复制token
PropertyTokenHolder getterTokens = new PropertyTokenHolder();
getterTokens.canonicalName = tokens.canonicalName;
getterTokens.actualName = tokens.actualName;
getterTokens.keys = new String[tokens.keys.length - 1];
System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);
Object propValue = null;
try {
//获取属性值,该方法内部使用JDK的内省( Introspector)机制,调用属性//的getter(readerMethod)方法,获取属性的值
propValue = getPropertyValue(getterTokens);
}
catch (NotReadablePropertyException ex) {
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
"Cannot access indexed value in property referenced " +
"in indexed property path '" + propertyName + "'", ex);
}
// Set value for last key.
获取集合类型属性的长度
String key = tokens.keys[tokens.keys.length - 1];
if (propValue == null) {
throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName,
"Cannot access indexed value in property referenced " +
"in indexed property path '" + propertyName + "': returned null");
}//数组处理
else if (propValue.getClass().isArray()) {
//数组属性
Class requiredType = propValue.getClass().getComponentType();
//数组长度
int arrayIndex = Integer.parseInt(key);
Object oldValue = null;
try {
if (isExtractOldValueForEditor()) {
oldValue = Array.get(propValue, arrayIndex);
}
Object convertedValue = this.typeConverterDelegate.convertIfNecessary(
propertyName, oldValue, pv.getValue(), requiredType);
Array.set(propValue, Integer.parseInt(key), convertedValue);
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new TypeMismatchException(pce, requiredType, ex);
}
catch (IndexOutOfBoundsException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Invalid array index in property path '" + propertyName + "'", ex);
}
}//注入list型的
else if (propValue instanceof List) {
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
//List里面的元素类型
Class requiredType = null;
if (JdkVersion.isAtLeastJava15()) {
requiredType = GenericCollectionTypeResolver.getCollectionReturnType(
pd.getReadMethod(), tokens.keys.length);
}
List list = (List) propValue;
int index = Integer.parseInt(key);
Object oldValue = null;
if (isExtractOldValueForEditor() && index < list.size()) {
oldValue = list.get(index);
}
try {
Object convertedValue = this.typeConverterDelegate.convertIfNecessary(
propertyName, oldValue, pv.getValue(), requiredType);
if (index < list.size()) {
list.set(index, convertedValue);
}
else if (index >= list.size()) {
for (int i = list.size(); i < index; i++) {
try {
list.add(null);
}
catch (NullPointerException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Cannot set element with index " + index + " in List of size " +
list.size() + ", accessed using property path '" + propertyName +
"': List does not support filling up gaps with null elements");
}
}
list.add(convertedValue);
}
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new TypeMismatchException(pce, requiredType, ex);
}
}
else if (propValue instanceof Map) {//map类型的
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
Class mapKeyType = null;
Class mapValueType = null;
if (JdkVersion.isAtLeastJava15()) {
mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(
pd.getReadMethod(), tokens.keys.length);
mapValueType = GenericCollectionTypeResolver.getMapValueReturnType(
pd.getReadMethod(), tokens.keys.length);
}
Map map = (Map) propValue;
Object convertedMapKey = null;
Object convertedMapValue = null;
try {
// IMPORTANT: Do not pass full property name in here - property editors
// must not kick in for map keys but rather only for map values.
convertedMapKey = this.typeConverterDelegate.convertIfNecessary(key, mapKeyType);
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, null, pv.getValue());
throw new TypeMismatchException(pce, mapKeyType, ex);
}
Object oldValue = null;
if (isExtractOldValueForEditor()) {
oldValue = map.get(convertedMapKey);
}
try {
// Pass full property name and old value in here, since we want full
// conversion ability for map values.
convertedMapValue = this.typeConverterDelegate.convertIfNecessary(
propertyName, oldValue, pv.getValue(), mapValueType, null,
new MethodParameter(pd.getReadMethod(), -1, tokens.keys.length + 1));
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new TypeMismatchException(pce, mapValueType, ex);
}
map.put(convertedMapKey, convertedMapValue);
}
else {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Property referenced in indexed property path '" + propertyName +
"' is neither an array nor a List nor a Map; returned value was [" + pv.getValue() + "]");
}
}
else {//
PropertyDescriptor pd = pv.resolvedDescriptor;
if (pd == null || !pd.getWriteMethod().getDeclaringClass().isInstance(this.object)) {
pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
if (pd == null || pd.getWriteMethod() == null) {
PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass());
throw new NotWritablePropertyException(
getRootClass(), this.nestedPath + propertyName,
matches.buildErrorMessage(), matches.getPossibleMatches());
}
pv.getOriginalPropertyValue().resolvedDescriptor = pd;
}
Object oldValue = null;
try {
Object originalValue = pv.getValue();
Object valueToApply = originalValue;
if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
if (pv.isConverted()) {
valueToApply = pv.getConvertedValue();
}
else {
if (isExtractOldValueForEditor() && pd.getReadMethod() != null) {
Method readMethod = pd.getReadMethod();
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
}
try {
oldValue = readMethod.invoke(this.object, new Object[0]);
}
catch (Exception ex) {
if (logger.isDebugEnabled()) {
logger.debug("Could not read previous value of property '" +
this.nestedPath + propertyName + "'", ex);
}
}
}
valueToApply = this.typeConverterDelegate.convertIfNecessary(oldValue, originalValue, pd);
}
pv.getOriginalPropertyValue().conversionNecessary = Boolean.valueOf(valueToApply != originalValue);
}
Method writeMethod = pd.getWriteMethod();
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
writeMethod.invoke(this.object, new Object[] {valueToApply});
}
catch (InvocationTargetException ex) {
PropertyChangeEvent propertyChangeEvent =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
if (ex.getTargetException() instanceof ClassCastException) {
throw new TypeMismatchException(propertyChangeEvent, pd.getPropertyType(), ex.getTargetException());
}
else {
throw new MethodInvocationException(propertyChangeEvent, ex.getTargetException());
}
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new TypeMismatchException(pce, pd.getPropertyType(), ex);
}
catch (IllegalAccessException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new MethodInvocationException(pce, ex);
}
}
}
通过对上面注入依赖代码的分析,我们已经明白了Spring IoC容器是如何将属性的值注入到Bean实例对象中去的:
(1).对于集合类型的属性,将其属性值解析为目标类型的集合后直接赋值给属性。
(2).对于非集合类型的属性,大量使用了JDK的反射和内省机制,通过属性的getter方法(reader method)获取指定属性注入以前的值,同时调用属性的setter方法(writer method)为属性设置注入后的值。看到这里相信很多人都明白了Spring的setter注入原理。
至此Spring IoC容器对Bean定义资源文件的定位,载入、解析和依赖注入已经全部分析完毕,现在Spring IoC容器中管理了一系列靠依赖关系联系起来的Bean,应用程序不需要自己手动创建所需的对象,Spring IoC容器会在我们使用的时候自动为我们创建,并且为我们注入好相关的依赖,这就是Spring核心功能的控制反转和依赖注入的相关功能。