Spring框架进阶Spring V3.0 DI源码分析流程
Posted 烟锁迷城
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring框架进阶Spring V3.0 DI源码分析流程相关的知识,希望对你有一定的参考价值。
目录
1、总体分析
1.1、依赖注入情形
在Spring框架中,实现getBean方法的类是AbstractBeanFactory。
在IOC完成对应的配置信息加载之后,IOC就可以开始对Bean进行管理了。但此时的Bean还没有完成依赖注入,只有经过依赖注入之后,才能继续使用。
Bean的依赖注入过程发生在两种情形下:
- 在getBean方法被首次调用的时候,触发依赖注入
- 在非懒加载的情况下,容器解析Bean时进行预实例化
1.2、实例化
在符合AOP代理条件的情形下,实例化的是对象的代理类,反之则实例化原生对象。
1.3、存储相关信息
将实例化的类封装到BeanWrapper之中,统一访问入口,拓展功能,缓存相关信息
1.4、关键方法
instantiateBean:实例化
populateBean:依赖注入
2、源码分析
ApplicationContext依旧是起始入口,但这次我们无法在这个类中找到需要的getBean方法,不过不要紧,还记得之前提到的ApplicationContext和DefaultListableBeanFactory都继承的类BeanFactory吗?getBean就在这里,而它的具体实现在抽象类AbstractBeanFactory之中
ApplicationContext调用AbstractBeanFactory的getBean方法,内部是doGetBean方法,即真正的执行方法。
Object sharedInstance = getSingleton(beanName),从三级缓存中获取到Bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null),如果缓存中的Bean不为空,且Object[]数组为空(必定为空),以此方法获取给定的实例,会尝试从缓存factoryBeanObjectCache 之中获取
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16)
如果缓存中没有,就使用Bean工厂尝试创建,成功后放入缓存factoryBeanObjectCach之中。
createBean(beanName, mbd, args),创建Bean的方法
public Object getBean(String name) throws BeansException
//doGetBean才是真正向IoC容器获取被管理Bean的过程
return doGetBean(name, null, null, false);
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException
//根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖
//如果指定的是别名,将别名转换为规范的Bean名称
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
//先从缓存中取是否已经有被创建过的单态类型的Bean
//对于单例模式的Bean整个IOC容器中只创建一次,不需要重复创建
Object sharedInstance = getSingleton(beanName);
//IOC容器创建单例模式Bean实例对象
if (sharedInstance != null && args == null)
if (logger.isDebugEnabled())
//如果指定名称的Bean在容器中已有单例模式的Bean被创建
//直接返回已经创建的Bean
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的实例对象,主要是完成FactoryBean的相关处理
//注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是
//创建创建对象的工厂Bean,两者之间有区别
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
else
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
//缓存没有正在创建的单例模式Bean
//缓存中已经有已经创建的原型模式Bean
//但是由于循环引用的问题导致实例化对象失败
if (isPrototypeCurrentlyInCreation(beanName))
throw new BeanCurrentlyInCreationException(beanName);
// Check if bean definition exists in this factory.
//对IOC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否
//能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器
//的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找
BeanFactory parentBeanFactory = getParentBeanFactory();
//当前容器的父级容器存在,且当前容器中不存在指定名称的Bean
if (parentBeanFactory != null && !containsBeanDefinition(beanName))
// Not found -> check parent.
//解析指定Bean名称的原始名称
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory)
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
else if (args != null)
// Delegation to parent with explicit args.
//委派父级容器根据指定名称和显式的参数查找
return (T) parentBeanFactory.getBean(nameToLookup, args);
else
// No args -> delegate to standard getBean method.
//委派父级容器根据指定名称和类型查找
return parentBeanFactory.getBean(nameToLookup, requiredType);
//创建的Bean是否需要进行类型验证,一般不需要
if (!typeCheckOnly)
//向容器标记指定的Bean已经被创建
markBeanAsCreated(beanName);
try
//根据指定Bean名称获取其父级的Bean定义
//主要解决Bean继承时子类合并父类公共属性问题
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
//获取当前Bean所有依赖Bean的名称
String[] dependsOn = mbd.getDependsOn();
//如果当前Bean有依赖Bean
if (dependsOn != null)
for (String dep : dependsOn)
if (isDependent(beanName, dep))
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
//递归调用getBean方法,获取当前Bean的依赖Bean
registerDependentBean(dep, beanName);
//把被依赖Bean注册给当前依赖的Bean
getBean(dep);
// Create bean instance.
//创建单例模式Bean的实例对象
if (mbd.isSingleton())
//这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
sharedInstance = getSingleton(beanName, () ->
try
//创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义
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.
//显式地从容器单例模式Bean缓存中清除实例对象
destroySingleton(beanName);
throw ex;
);
//获取给定Bean的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
//IOC容器创建原型模式Bean实例对象
else if (mbd.isPrototype())
// It's a prototype -> create a new instance.
//原型模式(Prototype)是每次都会创建一个新的对象
Object prototypeInstance = null;
try
//回调beforePrototypeCreation方法,默认的功能是注册当前创建的原型对象
beforePrototypeCreation(beanName);
//创建指定Bean对象实例
prototypeInstance = createBean(beanName, mbd, args);
finally
//回调afterPrototypeCreation方法,默认的功能告诉IOC容器指定Bean的原型对象不再创建
afterPrototypeCreation(beanName);
//获取给定Bean的实例对象
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
//要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中
//配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中
//比较常用,如:request、session、application等生命周期
else
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
//Bean定义资源中没有配置生命周期范围,则Bean定义不合法
if (scope == null)
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
try
//这里又使用了一个匿名内部类,获取一个指定生命周期范围的实例
Object scopedInstance = scope.get(beanName, () ->
beforePrototypeCreation(beanName);
try
return createBean(beanName, mbd, args);
finally
afterPrototypeCreation(beanName);
);
//获取给定Bean的实例对象
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);
catch (BeansException ex)
cleanupAfterBeanCreationFailure(beanName);
throw ex;
// Check if required type matches the type of the actual bean instance.
//对创建的Bean实例对象进行类型检查
if (requiredType != null && !requiredType.isInstance(bean))
try
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null)
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
return convertedBean;
catch (TypeMismatchException ex)
if (logger.isDebugEnabled())
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
return (T) bean;
createBean是创建Bean的方法,在这里执行真正的执行方法doCreateBean
resolveBeanClass方法确定是否可以由当前的类加载器进行加载,这涉及到双亲委派,如果这个类加载器无法获取到,就交给父类加载器进行加载,直至顶级类加载器,如果还是没有,就交给子类加载器去创建。
但首次执行,这里肯定没有,所以一定会去执行真正的创建方法,doGreateBean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable 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.
//判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null)
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
// Prepare method overrides.
//校验和准备Bean中的方法覆盖
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.
//如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象
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);
try
//创建Bean的入口
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled())
logger.debug("Finished creating instance of bean '" + beanName + "'");
return beanInstance;
catch (BeanCreationException ex)
// A previously detected exception with proper bean creation context already...
throw ex;
catch (ImplicitlyAppearedSingletonException ex)
// An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
throw ex;
catch (Throwable ex)
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
在doCreateBean方法里,准备好了用来封装的类BeanWrapper。
如果没有从缓存中获取到封装对象,就执行createBeanInstance创建方法,参数除了beanName,BeanDefinition之外,还有构造函数的参数,因为实例化时,使用的构造函数未必是无参。
用来保存BeanWrapper的缓存为factoryBeanInstanceCache
private final Map<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>(16);
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException
// Instantiate the bean.
//封装被创建的Bean对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton())
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
if (instanceWrapper == null)
instanceWrapper = createBeanInstance(beanName, mbd, args);
final Object bean = instanceWrapper.getWrappedInstance();
//获取实例化对象的类型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class)
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
//调用PostProcessor后置处理器
synchronized (mbd.postProcessingLock)
if (!mbd.postProcessed)
try
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
catch (Throwable ex)
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
mbd.postProcessed = true;
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//向容器中缓存单例模式的Bean对象,以防循环引用
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, () -> getEarlyBeanReference(beanName, mbd, bean));
// Initialize the bean instance.
//Bean对象的初始化,依赖注入在此触发
//这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean
Object exposedObject = bean;
try
//将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
populateBean(beanName, mbd, instanceWrapper);
//初始化Bean对象
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)
//获取指定名称的已注册的单例模式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<>(dependentBeans.length);
//获取当前Bean所依赖的其他Bean
for (String dependentBean : dependentBeans)
//对依赖Bean进行类型检查
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.
//注册完成依赖注入的Bean
try
registerDisposableBeanIfNecessary(beanName, bean, mbd);
catch (BeanDefinitionValidationException ex)
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
return exposedObject;
实例化Bean方法,将执行对应的策略getInstantiationStrategy().instantiate(mbd, beanName, parent)
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd)
try
Object beanInstance;
final BeanFactory parent = this;
//获取系统的安全管理接口,JDK标准的安全管理API
if (System.getSecurityManager() != null)
//这里是一个匿名内置类,根据实例化策略创建实例对象
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
else
//将实例化的对象封装起来
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
catch (Throwable ex)
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
SimpleInstantiationStrategy类中,进入到对应策略之中,如果该类没有重写过方法,就不再执行CGLIB的实现方法。
接下来获取构造或工厂方法,如果此类为接口,不再执行构建,反之则构建需要的参数,最后执行BeanUtils.instantiateClass完成实例化。
如果有重写,则将执行CGLIB的类CglibSubclassingInstantiationStrategy策略,它继承了SimpleInstantiationStrategy,执行的方法是instantiateWithMethodInjection,这个方法调用了重写的instantiate方法,依旧执行BeanUtils.instantiateClass。
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)
// Don't override the class with CGLIB if no overrides.
//如果Bean定义中没有方法覆盖,则就不需要CGLIB父类类的方法
if (!bd.hasMethodOverrides())
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock)
//获取对象的构造方法或工厂方法
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
//如果没有构造方法且没有工厂方法
if (constructorToUse == null)
//使用JDK的反射机制,判断要实例化的Bean是否是接口
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface())
throw new BeanInstantiationException(clazz, "Specified class is an interface");
try
if (System.getSecurityManager() != null)
//这里是一个匿名内置类,使用反射机制获取Bean的构造方法
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) () -> clazz.getDeclaredConstructor());
else
constructorToUse = clazz.getDeclaredConstructor();
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
catch (Throwable ex)
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
//使用BeanUtils实例化,通过反射机制调用”构造方法.newInstance(arg)”来进行实例化
return BeanUtils.instantiateClass(constructorToUse);
else
// Must generate CGLIB subclass.
//使用CGLIB来实例化对象
return instantiateWithMethodInjection(bd, beanName, owner);
KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ? KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args)
获取到构造的所属类,进行判断。
KotlinDelegate.instantiateClass(ctor, args):使用有参构造实现
ctor.newInstance(args):使用无参构造完成
对于newInstance方法而言,如果传入参数就是使用有参构造,但如果传入的数组为空或长度为0,实际调用的则是无参构造
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException
Assert.notNull(ctor, "Constructor must not be null");
try
ReflectionUtils.makeAccessible(ctor);
return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
catch (InstantiationException ex)
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
catch (IllegalAccessException ex)
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
catch (IllegalArgumentException ex)
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
catch (InvocationTargetException ex)
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
接下来继续看populateBean方法,在这个方法中,将beanName,BeanDefinition,BeanWrapper作为条件找到需要复制的属性并封装在PropertyValues集合之中
PropertyValues内的属性PropertyValue列表,每一个PropertyValue都保存着需要赋值的类Bean,需要调用的方法和赋予的数值
真正要执行的方法,其实是在处置之后得到数值的PropertyValues不为空时执行的方法
applyPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
if (bw == null)
if (mbd.hasPropertyValues())
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 (BeanPostProcessor bp : getBeanPostProcessors())
if (bp instanceof InstantiationAwareBeanPostProcessor)
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName))
continueWithPropertyPopulation = false;
break;
if (!continueWithPropertyPopulation)
return;
//获取容器在解析Bean定义资源时为BeanDefiniton中设置的属性值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//对依赖注入处理,首先处理autowiring自动装配的依赖注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE)
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
//根据Bean名称进行autowiring自动装配处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME)
autowireByName(beanName, mbd, bw, newPvs);
// Add property values based on autowire by type if applicable.
//根据Bean类型进行autowiring自动装配处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE)
autowireByType(beanName, mbd, bw, newPvs);
pvs = newPvs;
//对非autowiring的属性进行依赖注入处理
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck)
if (pvs == null)
pvs = mbd.getPropertyValues();
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps)
for (BeanPostProcessor bp : getBeanPostProcessors())
if (bp instanceof InstantiationAwareBeanPostProcessor)
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null)
return;
if (needsDepCheck)
checkDependencies(beanName, mbd, filteredPds, pvs);
if (pvs != null)
//对属性进行注入
applyPropertyValues(beanName, mbd, bw, pvs);
applyPropertyValues方法,继续创造注入,处理数据,最终要执行的方法,是setPropertyValues
bw.setPropertyValues(new MutablePropertyValues(deepCopy))
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs)
if (pvs.isEmpty())
return;
//封装属性值
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (System.getSecurityManager() != null)
if (bw instanceof BeanWrapperImpl)
//设置安全上下文,JDK安全机制
((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());
//获取用户自定义的类型转换
TypeConverter converter = getCustomTypeConverter();
if (converter == null)
converter = bw;
//创建一个Bean定义属性值解析器,将Bean定义中的属性值解析为Bean实例对象的实际值
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
//为属性的解析值创建一个拷贝,将拷贝的数据注入到实例对象中
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original)
//属性值不需要转换
if (pv.isConverted())
deepCopy.add(pv);
//属性值需要转换
else
String propertyName = pv.getName();
//原始的属性值,即转换之前的属性值
Object originalValue = pv.getValue();
//转换属性值,例如将引用转换为IOC容器中实例化对象引用
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();
// Set our (possibly massaged) deep copy.
//进行属性依赖注入
try
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
catch (BeansException ex)
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
setPropertyValues方法,使用访问者模式,给数据结构和数据操作解耦
继续查看重写方法,可以看到这里有一个循环,因为依赖注入的数据时一次性批量处理的,全部在一个容器PropertyValues中
循环内部,setPropertyValue方法继续注入
public void setPropertyValues(PropertyValues pvs) throws BeansException
setPropertyValues(pvs, false, false);
public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
throws BeansException
List<PropertyAccessException> propertyAccessExceptions = null;
List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
for (PropertyValue pv : propertyValues)
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 =
propertyAccessExceptions.toArray(new PropertyAccessException[propertyAccessExceptions.size()]);
throw new PropertyBatchUpdateException(paeArray);
以tokens是否为空做为判断依据,继续执行方法,但可以看到,其实这两个方法将走入一个判断中
public void setPropertyValue(PropertyValue pv) throws BeansException
PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
if (tokens == null)
String propertyName = pv.getName();
AbstractNestablePropertyAccessor nestedPa;
try
nestedPa = getPropertyAccessorForPropertyPath(propertyName);
catch (NotReadablePropertyException ex)
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
"Nested property in path '" + propertyName + "' does not exist", ex);
tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));
if (nestedPa == this)
pv.getOriginalPropertyValue().resolvedTokens = tokens;
nestedPa.setPropertyValue(tokens, pv);
else
setPropertyValue(tokens, pv);
跳转至processLocalProperty方法内,在这里继续执行ph.setValue(valueToApply)方法
protected void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException
if (tokens.keys != null)
processKeyedProperty(tokens, pv);
else
processLocalProperty(tokens, pv);
private void processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv)
PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);
if (ph == null || !ph.isWritable())
if (pv.isOptional())
if (logger.isDebugEnabled())
logger.debug("Ignoring optional value for property '" + tokens.actualName +
"' - property not found on bean class [" + getRootClass().getName() + "]");
return;
else
throw createNotWritablePropertyException(tokens.canonicalName);
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() && ph.isReadable())
try
oldValue = ph.getValue();
catch (Exception ex)
if (ex instanceof PrivilegedActionException)
ex = ((PrivilegedActionException) ex).getException();
if (logger.isDebugEnabled())
logger.debug("Could not read previous value of property '" +
this.nestedPath + tokens.canonicalName + "'", ex);
valueToApply = convertForProperty(
tokens.canonicalName, oldValue, originalValue, ph.toTypeDescriptor());
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
ph.setValue(valueToApply);
catch (TypeMismatchException ex)
throw ex;
catch (InvocationTargetException ex)
PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(
getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
if (ex.getTargetException() instanceof ClassCastException)
throw new TypeMismatchException(propertyChangeEvent, ph.getPropertyType(), ex.getTargetException());
else
Throwable cause = ex.getTargetException();
if (cause instanceof UndeclaredThrowableException)
// May happen e.g. with Groovy-generated methods
cause = cause.getCause();
throw new MethodInvocationException(propertyChangeEvent, cause);
catch (Exception ex)
PropertyChangeEvent pce = new PropertyChangeEvent(
getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
throw new MethodInvocationException(pce, ex);
最终,以反射调用方法进行注入,这里的writeMethod实际上是setter方法,也就是说,使用反射调用setter方法进行依赖注入
public void setValue(final @Nullable Object value) throws Exception
final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
this.pd.getWriteMethod());
if (System.getSecurityManager() != null)
AccessController.doPrivileged((PrivilegedAction<Object>) () ->
ReflectionUtils.makeAccessible(writeMethod);
return null;
);
try
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
writeMethod.invoke(getWrappedInstance(), value), acc);
catch (PrivilegedActionException ex)
throw ex.getException();
else
ReflectionUtils.makeAccessible(writeMethod);
writeMethod.invoke(getWrappedInstance(), value);
3、流程总结
3.1、实例化
ApplicationContext:起始类,这个类中本身没有getBean方法,但是因为继承BeanFactory类,所以具有getBean方法,真正实现getBean方法的是AbstractBeanFactory
getBean:执行依赖注入的方法,获取到Bean
AbstractBeanFactory:
doGetBean:真正执行getBean的方法
AbstractBeanFactory:
createBean:创建Bean的方法
AbstractAutowireCapableBeanFactory:
doCreateBean:中以BeanWrapper进行封装
AbstractAutowireCapableBeanFactory:
createBeanInstance:创建Bean实例,与populateBean同在AbstractAutowireCapableBeanFactory
SimpleInstantiationStrategy:
instantiate:根据条件执行不同策略的代理方式,最后以反射实现实例化
3.2、依赖注入
populateBean:依赖注入,与createBeanInstance同在AbstractAutowireCapableBeanFactory,将beanName,BeanDefinition,BeanWrapper作为条件找到需要复制的属性并封装在PropertyValues集合之中
PropertyValues内的属性PropertyValue列表,每一个PropertyValue都保存着需要赋值的类Bean,需要调用的方法和赋予的数值
AbstractAutowireCapableBeanFactory:
applyPropertyValues:处理依照不同方式注入的数值之后,开始依赖注入。属于AbstractAutowireCapableBeanFactory
AbstractAutowireCapableBeanFactory:
setPropertyValues:使用访问者模式
AbstractPropertyAccessor:
setPropertyValue:PropertyValues将需要的依赖注入值保存到内部列表中,是一种迭代器加组合模式,之后循环执行此方法,进行注入依赖
AbstractNestablePropertyAccessor:
processLocalProperty:
AbstractNestablePropertyAccessor:
setValue:反射调用,将依赖注入
BeanWrapperImpl:
以上是关于Spring框架进阶Spring V3.0 DI源码分析流程的主要内容,如果未能解决你的问题,请参考以下文章