相关内容:
架构师系列内容:架构师学习笔记(持续更新)
一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程)
一步一步手绘Spring IOC运行时序图二(基于XML的IOC容器初始化)
一步一步手绘Spring IOC运行时序图三(基于Annotation的IOC容器初始化)
一步一步手绘Spring DI运行时序图(Spring 自动装配之依赖注入)
一步一步手绘Spring AOP运行时序图(Spring AOP 源码分析)
一步一步手绘Spring MVC运行时序图(Spring MVC原理)

1、Spring 自动装配之依赖注入

依赖注入的关键类

1、IOC容器 : BeanFactory getBean()、AbstractBeanFactory
2、实例化策略 : SimpleInstantiationStrategy
3、存储实例所有相关的信息scope、proxy、instance :BeanWrapper

依赖注入执行细节

依赖注入发生的时间

当 Spring IOC 容器完成了 Bean 定义资源的定位、载入和解析注册以后,IOC 容器中已经管理类 Bean定义的相关数据,但是此时 IOC 容器还没有对所管理的 Bean 进行依赖注入,依赖注入在以下两种情况发生:
1)、用户第一次调用 getBean()方法时,IOC 容器触发依赖注入。
2)、当用户在配置文件中将元素配置了 lazy-init=false 属性,即让容器在解析注册 Bean 定义时进行预实例化,触发依赖注入。

BeanFactory 接口定义了 Spring IOC 容器的基本功能规范,是 Spring IOC 容器所应遵守的最底层和最基本的编程规范。BeanFactory 接口中定义了几个 getBean()方法,就是用户向 IOC 容器索取管理的Bean 的方法,我们通过分析其子类的具体实现,理解 Spring IOC 容器在用户索取 Bean 时如何完成依赖注入。

在 BeanFactory 中我们可以看到 getBean(String…)方法,但它具体实现在 AbstractBeanFactory 中。

2、实例化过程

寻找获取 Bean 的入口

AbstractBeanFactory 的 getBean()相关方法的源码如下:

public interface BeanFactory {//对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,//如果需要得到工厂本身,需要转义String FACTORY_BEAN_PREFIX = "&";//根据bean的名字,获取在IOC容器中得到bean实例Object getBean(String name) throws BeansException;//根据bean的名字和Class类型来得到bean实例,增加了类型安全验证机制。<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;Object getBean(String name, Object... args) throws BeansException;<T> T getBean(Class<T> requiredType) throws BeansException;<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;//提供对bean的检索,看看是否在IOC容器有这个名字的beanboolean containsBean(String name);//根据bean名字得到bean实例,并同时判断这个bean是不是单例boolean isSingleton(String name) throws NoSuchBeanDefinitionException;boolean isPrototype(String name) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;//得到bean实例的Class类型@NullableClass<?> getType(String name) throws NoSuchBeanDefinitionException;//得到bean的别名,如果根据别名检索,那么其原名也会被检索出来String[] getAliases(String name);}
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {//获取IOC容器中指定名称的Bean@Overridepublic Object getBean(String name) throws BeansException {//doGetBean才是真正向IoC容器获取被管理Bean的过程return doGetBean(name, null, null, false);}//获取IOC容器中指定名称和类型的Bean@Overridepublic <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {//doGetBean才是真正向IoC容器获取被管理Bean的过程return doGetBean(name, requiredType, null, false);}//获取IOC容器中指定名称和参数的Bean@Overridepublic Object getBean(String name, Object... args) throws BeansException {//doGetBean才是真正向IoC容器获取被管理Bean的过程return doGetBean(name, null, args, false);}//获取IOC容器中指定名称、类型和参数的Beanpublic <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)throws BeansException {//doGetBean才是真正向IoC容器获取被管理Bean的过程return doGetBean(name, requiredType, args, false);}@SuppressWarnings("unchecked")//真正实现向IOC容器获取Bean的功能,也是触发依赖注入功能的地方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被创建//直接返回已经创建的Beanif (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();//当前容器的父级容器存在,且当前容器中不存在指定名称的Beanif (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有依赖Beanif (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的依赖BeanregisterDependentBean(dep, beanName);//把被依赖Bean注册给当前依赖的BeangetBean(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;}//获取给定Bean的实例对象,主要是完成FactoryBean的相关处理protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {// Don't let calling code try to dereference the factory if the bean isn't a factory.//容器已经得到了Bean实例对象,这个实例对象可能是一个普通的Bean,//也可能是一个工厂Bean,如果是一个工厂Bean,则使用它创建一个Bean实例对象,//如果调用本身就想获得一个容器的引用,则指定返回这个工厂Bean实例对象//如果指定的名称是容器的解引用(dereference,即是对象本身而非内存地址),//且Bean实例也不是创建Bean实例对象的工厂Beanif (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());}// Now we have the bean instance, which may be a normal bean or a FactoryBean.// If it's a FactoryBean, we use it to create a bean instance, unless the// caller actually wants a reference to the factory.//如果Bean实例不是工厂Bean,或者指定名称是容器的解引用,//调用者向获取对容器的引用,则直接返回当前的Bean实例if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {return beanInstance;}//处理指定名称不是容器的解引用,或者根据名称获取的Bean实例对象是一个工厂Bean//使用工厂Bean创建一个Bean的实例对象Object object = null;if (mbd == null) {//从Bean工厂缓存中获取给定名称的Bean实例对象object = getCachedObjectForFactoryBean(beanName);}//让Bean工厂生产给定名称的Bean对象实例if (object == null) {// Return bean instance from factory.FactoryBean<?> factory = (FactoryBean<?>) beanInstance;// Caches object obtained from FactoryBean if it is a singleton.//如果从Bean工厂生产的Bean是单态模式的,则缓存if (mbd == null && containsBeanDefinition(beanName)) {//从容器中获取指定名称的Bean定义,如果继承基类,则合并基类相关属性mbd = getMergedLocalBeanDefinition(beanName);}//如果从容器得到Bean定义信息,并且Bean定义信息不是虚构的,//则让工厂Bean生产Bean实例对象boolean synthetic = (mbd != null && mbd.isSynthetic());//调用FactoryBeanRegistrySupport类的getObjectFromFactoryBean方法,//实现工厂Bean生产Bean对象实例的过程object = getObjectFromFactoryBean(factory, beanName, !synthetic);}return object;}
}

通过上面对向 IOC 容器获取 Bean 方法的分析,我们可以看到在 Spring 中,如果 Bean 定义的单例模式(Singleton),则容器在创建之前先从缓存中查找,以确保整个容器中只存在一个实例对象。如果 Bean定义的是原型模式(Prototype),则容器每次都会创建一个新的实例对象。除此之外,Bean 定义还可以扩展为指定其生命周期范围。
上面的源码只是定义了根据 Bean 定义的模式,采取的不同创建 Bean 实例对象的策略,具体的 Bean实例对象的创建过程由实现了 BeanFactory 接口的匿名内部类的 createBean()方法完成, BeanFactory 使用委派模式 , 具体的 Bean 实例创建过程交由其实现类AbstractAutowireCapableBeanFactory 完成,我们继续分析 AbstractAutowireCapableBeanFactory的 createBean()方法的源码,理解其创建 Bean 实例的具体实现过程。

开始实例化

AbstractAutowireCapableBeanFactory 类实现了 BeanFactory 接口,创建容器指定的 Bean 实例对象,同时还对创建的 Bean 实例对象进行初始化处理。其创建 Bean 实例对象的方法源码如下:

//创建Bean实例对象
@Override
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);}
}//真正创建Bean的方法
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在初始化完成之后返回作为依赖注入完成后的BeanObject 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所依赖的其他Beanfor (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.//注册完成依赖注入的Beantry {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;
}

通过上面的源码注释,我们看到具体的依赖注入实现其实就在以下两个方法中:
1)、createBeanInstance()方法,生成 Bean 所包含的 java 对象实例。
2)、populateBean()方法,对 Bean 属性的依赖注入进行处理。

下面继续分析这两个方法的代码实现:

选择 Bean 实例化策略

在 createBeanInstance()方法中,根据指定的初始化策略,使用简单工厂、工厂方法或者容器的自动装配特性生成 Java 实例对象,创建对象的源码如下:

//创建Bean的实例对象
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// Make sure bean class is actually resolved at this point.//检查确认Bean是可实例化的Class<?> beanClass = resolveBeanClass(mbd, beanName);//使用工厂方法对Bean进行实例化if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());}Supplier<?> instanceSupplier = mbd.getInstanceSupplier();if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);}if (mbd.getFactoryMethodName() != null)  {//调用工厂方法实例化return instantiateUsingFactoryMethod(beanName, mbd, args);}// Shortcut when re-creating the same bean...//使用容器的自动装配方法进行实例化boolean resolved = false;boolean autowireNecessary = false;if (args == null) {synchronized (mbd.constructorArgumentLock) {if (mbd.resolvedConstructorOrFactoryMethod != null) {resolved = true;autowireNecessary = mbd.constructorArgumentsResolved;}}}if (resolved) {if (autowireNecessary) {//配置了自动装配属性,使用容器的自动装配实例化//容器的自动装配是根据参数类型匹配Bean的构造方法return autowireConstructor(beanName, mbd, null, null);}else {//使用默认的无参构造方法实例化return instantiateBean(beanName, mbd);}}// Need to determine the constructor...//使用Bean的构造方法进行实例化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);
}//使用默认的无参构造方法实例化Bean对象
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {try {Object beanInstance;final BeanFactory parent = this;//获取系统的安全管理接口,JDK标准的安全管理APIif (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);}
}

经过对上面的代码分析,我们可以看出,对使用工厂方法和自动装配特性的 Bean 的实例化相当比较清楚,调用相应的工厂方法或者参数匹配的构造方法即可完成实例化对象的工作,但是对于我们最常使用的默认无参构造方法就需要使用相应的初始化策略(JDK 的反射机制或者 CGLib)来进行初始化了,在方法 getInstantiationStrategy().instantiate()中就具体实现类使用初始策略实例化对象。

执行 Bean 实例化

在使用默认的无参构造方法创建 Bean 的实例化对象时,方法 getInstantiationStrategy().instantiate()调用了 SimpleInstantiationStrategy 类中的实例化 Bean 的方法,其源码如下:

//使用初始化策略实例化Bean对象
@Override
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);}
}

通过上面的代码分析,我们看到了如果 Bean 有方法被覆盖了,则使用 JDK 的反射机制进行实例化,否则,使用 CGLib 进行实例化。
instantiateWithMethodInjection() 方法调用 SimpleInstantiationStrategy 的子类CGLibSubclassingInstantiationStrategy 使用 CGLib 来进行初始化,其源码如下:

//使用CGLIB进行Bean对象实例化public Object instantiate(@Nullable Constructor<?> ctor, @Nullable Object... args) {//创建代理子类Class<?> subclass = createEnhancedSubclass(this.beanDefinition);Object instance;if (ctor == null) {instance = BeanUtils.instantiateClass(subclass);}else {try {Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());instance = enhancedSubclassConstructor.newInstance(args);}catch (Exception ex) {throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);}}// SPR-10785: set callbacks directly on the instance instead of in the// enhanced class (via the Enhancer) in order to avoid memory leaks.Factory factory = (Factory) instance;factory.setCallbacks(new Callback[] {NoOp.INSTANCE,new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});return instance;}/*** Create an enhanced subclass of the bean class for the provided bean* definition, using CGLIB.*/private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {//CGLIB中的类Enhancer enhancer = new Enhancer();//将Bean本身作为其基类enhancer.setSuperclass(beanDefinition.getBeanClass());enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);if (this.owner instanceof ConfigurableBeanFactory) {ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));}enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));enhancer.setCallbackTypes(CALLBACK_TYPES);//使用CGLIB的createClass方法生成实例对象return enhancer.createClass();}
}

CGLib 是一个常用的字节码生成器的类库,它提供了一系列 API 实现 Java 字节码的生成和转换功能。我们在学习 JDK 的动态代理时都知道,JDK 的动态代理只能针对接口,如果一个类没有实现任何接口,要对其进行动态代理只能使用 CGLib。

准备依赖注入

在前面的分析中我们已经了解到 Bean 的依赖注入主要分为两个步骤,首先调用 createBeanInstance()方法生成 Bean 所包含的 Java 对象实例。然后,调用 populateBean()方法,对 Bean 属性的依赖注入进行处理。

上面我们已经分析了容器初始化生成 Bean 所包含的 Java 实例对象的过程,现在我们继续分析生成对象后,Spring IOC 容器是如何将 Bean 的属性依赖关系注入 Bean 实例对象中并设置好的,回到AbstractAutowireCapableBeanFactory 的 populateBean()方法,对属性依赖注入的代码如下:

//将Bean属性设置到生成的实例对象上
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);}
}//解析并注入依赖属性的过程
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);}
}

分析上述代码,我们可以看出,对属性的注入过程分以下两种情况:
1)、属性值类型不需要强制转换时,不需要解析属性值,直接准备进行依赖注入。
2)、属性值需要进行类型强制转换时,如对其他对象的引用等,首先需要解析属性值,然后对解析后的属性值进行依赖注入。

对属性值的解析是在 BeanDefinitionValueResolver 类中的 resolveValueIfNecessary()方法中进行的,对属性值的依赖注入是通过 bw.setPropertyValues()方法实现的,在分析属性值的依赖注入之前,我们先分析一下对属性值的解析过程。

解析属性注入规则

当容器在对属性进行依赖注入时,如果发现属性值需要进行类型转换,如属性值是容器中另一个 Bean实例对象的引用,则容器首先需要根据属性值解析出所引用的对象,然后才能将该引用对象注入到目标实例对象的属性上去,对属性进行解析的由 resolveValueIfNecessary()方法实现,其源码如下:

//解析属性值,对注入类型进行转换
@Nullable
public Object resolveValueIfNecessary(Object argName, @Nullable 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 refName = ((RuntimeBeanNameReference) value).getBeanName();refName = String.valueOf(doEvaluate(refName));//从容器中获取指定名称的Beanif (!this.beanFactory.containsBean(refName)) {throw new BeanDefinitionStoreException("Invalid bean name '" + refName + "' in bean reference for " + argName);}return refName;}//对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;String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +ObjectUtils.getIdentityHexString(bd);return resolveInnerBean(argName, innerBeanName, bd);}//对集合数组类型的属性解析else if (value instanceof ManagedArray) {// May need to resolve contained runtime references.ManagedArray array = (ManagedArray) value;//获取数组的类型Class<?> elementType = array.resolvedElementType;if (elementType == null) {//获取数组元素的类型String elementTypeName = array.getElementTypeName();if (StringUtils.hasText(elementTypeName)) {try {//使用反射机制创建指定类型的对象elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());array.resolvedElementType = elementType;}catch (Throwable ex) {// Improve the message by showing the context.throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,"Error resolving array type for " + argName, ex);}}//没有获取到数组的类型,也没有获取到数组元素的类型//则直接设置数组的类型为Objectelse {elementType = Object.class;}}//创建指定类型的数组return resolveManagedArray(argName, (List<?>) value, elementType);}//解析list类型的属性值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均为字符串的mapelse if (value instanceof ManagedProperties) {Properties original = (Properties) value;//创建一个拷贝,用于作为解析后的返回值Properties copy = new Properties();original.forEach((propKey, propValue) -> {if (propKey instanceof TypedStringValue) {propKey = evaluate((TypedStringValue) propKey);}if (propValue instanceof TypedStringValue) {propValue = evaluate((TypedStringValue) propValue);}if (propKey == null || propValue == null) {throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,"Error converting Properties key/value pair for " + argName + ": resolved to null");}copy.put(propKey, propValue);});return copy;}//解析字符串类型的属性值else if (value instanceof TypedStringValue) {// Convert value to target type here.TypedStringValue typedStringValue = (TypedStringValue) value;Object valueObject = evaluate(typedStringValue);try {//获取属性的目标类型Class<?> resolvedTargetType = resolveTargetType(typedStringValue);if (resolvedTargetType != null) {//对目标类型的属性进行解析,递归调用return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);}//没有获取到属性的目标对象,则按Object类型返回else {return valueObject;}}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 if (value instanceof NullBean) {return null;}else {return evaluate(value);}
}//解析引用类型的属性值
@Nullable
private Object resolveReference(Object argName, RuntimeBeanReference ref) {try {Object bean;//获取引用的Bean名称String refName = ref.getBeanName();refName = String.valueOf(doEvaluate(refName));//如果引用的对象在父类容器中,则从父类容器中获取指定的引用对象if (ref.isToParent()) {if (this.beanFactory.getParentBeanFactory() == null) {throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,"Can't resolve reference to bean '" + refName +"' in parent factory: no parent factory available");}bean = this.beanFactory.getParentBeanFactory().getBean(refName);}//从当前的容器中获取指定的引用Bean对象,如果指定的Bean没有被实例化//则会递归触发引用Bean的初始化和依赖注入else {bean = this.beanFactory.getBean(refName);//将当前实例化对象的依赖引用对象this.beanFactory.registerDependentBean(refName, this.beanName);}if (bean instanceof NullBean) {bean = null;}return bean;}catch (BeansException ex) {throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);}
}/**
* For each element in the managed array, resolve reference if necessary.
*/
//解析array类型的属性
private Object resolveManagedArray(Object argName, List<?> ml, Class<?> elementType) {//创建一个指定类型的数组,用于存放和返回解析后的数组Object resolved = Array.newInstance(elementType, ml.size());for (int i = 0; i < ml.size(); i++) {//递归解析array的每一个元素,并将解析后的值设置到resolved数组中,索引为iArray.set(resolved, i,resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));}return resolved;
}/**
* For each element in the managed list, resolve reference if necessary.
*/
//解析list类型的属性
private List<?> resolveManagedList(Object argName, List<?> ml) {List<Object> resolved = new ArrayList<>(ml.size());for (int i = 0; i < ml.size(); i++) {//递归解析list的每一个元素resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));}return resolved;
}/**
* For each element in the managed set, resolve reference if necessary.
*/
//解析set类型的属性
private Set<?> resolveManagedSet(Object argName, Set<?> ms) {Set<Object> resolved = new LinkedHashSet<>(ms.size());int i = 0;//递归解析set的每一个元素for (Object m : ms) {resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), m));i++;}return resolved;
}/**
* For each element in the managed map, resolve reference if necessary.
*/
//解析map类型的属性
private Map<?, ?> resolveManagedMap(Object argName, Map<?, ?> mm) {Map<Object, Object> resolved = new LinkedHashMap<>(mm.size());//递归解析map中每一个元素的key和valuefor (Map.Entry<?, ?> entry : mm.entrySet()) {Object resolvedKey = resolveValueIfNecessary(argName, entry.getKey());Object resolvedValue = resolveValueIfNecessary(new KeyedArgName(argName, entry.getKey()), entry.getValue());resolved.put(resolvedKey, resolvedValue);}return resolved;
}

通过上面的代码分析,我们明白了 Spring 是如何将引用类型,内部类以及集合类型等属性进行解析的,属性值解析完成后就可以进行依赖注入了,依赖注入的过程就是 Bean 对象实例设置到它所依赖的 Bean对象属性上去。而真正的依赖注入是通过 bw.setPropertyValues()方法实现的,该方法也使用了委托模式 , 在 BeanWrapper 接 口 中 至 少 定 义 了 方 法 声 明 , 依 赖 注 入 的 具 体 实 现 交 由 其 实 现 类BeanWrapperImpl 来完成,下面我们就分析依 BeanWrapperImpl 中赖注入相关的源码。

注入赋值

BeanWrapperImpl 类主要是对容器中完成初始化的 Bean 实例对象进行属性的依赖注入,即把 Bean对象设置到它所依赖的另一个 Bean 的属性中去。然而,BeanWrapperImpl 中的注入方法实际上由AbstractNestablePropertyAccessor 来实现的,其相关源码如下:

//实现属性依赖注入功能
protected void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {if (tokens.keys != null) {processKeyedProperty(tokens, pv);}else {processLocalProperty(tokens, pv);}
}//实现属性依赖注入功能
@SuppressWarnings("unchecked")
private void processKeyedProperty(PropertyTokenHolder tokens, PropertyValue pv) {//调用属性的getter方法,获取属性的值Object propValue = getPropertyHoldingValue(tokens);PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);if (ph == null) {throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.actualName, "No property handler found");}Assert.state(tokens.keys != null, "No token keys");String lastKey = tokens.keys[tokens.keys.length - 1];//注入array类型的属性值if (propValue.getClass().isArray()) {Class<?> requiredType = propValue.getClass().getComponentType();int arrayIndex = Integer.parseInt(lastKey);Object oldValue = null;try {if (isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) {oldValue = Array.get(propValue, arrayIndex);}Object convertedValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),requiredType, ph.nested(tokens.keys.length));//获取集合类型属性的长度int length = Array.getLength(propValue);if (arrayIndex >= length && arrayIndex < this.autoGrowCollectionLimit) {Class<?> componentType = propValue.getClass().getComponentType();Object newArray = Array.newInstance(componentType, arrayIndex + 1);System.arraycopy(propValue, 0, newArray, 0, length);setPropertyValue(tokens.actualName, newArray);//调用属性的getter方法,获取属性的值propValue = getPropertyValue(tokens.actualName);}//将属性的值赋值给数组中的元素Array.set(propValue, arrayIndex, convertedValue);}catch (IndexOutOfBoundsException ex) {throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,"Invalid array index in property path '" + tokens.canonicalName + "'", ex);}}//注入list类型的属性值else if (propValue instanceof List) {//获取list集合的类型Class<?> requiredType = ph.getCollectionType(tokens.keys.length);List<Object> list = (List<Object>) propValue;//获取list集合的sizeint index = Integer.parseInt(lastKey);Object oldValue = null;if (isExtractOldValueForEditor() && index < list.size()) {oldValue = list.get(index);}//获取list解析后的属性值Object convertedValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),requiredType, ph.nested(tokens.keys.length));int size = list.size();//如果list的长度大于属性值的长度,则多余的元素赋值为nullif (index >= size && index < this.autoGrowCollectionLimit) {for (int i = size; i < index; i++) {try {list.add(null);}catch (NullPointerException ex) {throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,"Cannot set element with index " + index + " in List of size " +size + ", accessed using property path '" + tokens.canonicalName +"': List does not support filling up gaps with null elements");}}list.add(convertedValue);}else {try {//将值添加到list中list.set(index, convertedValue);}catch (IndexOutOfBoundsException ex) {throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,"Invalid list index in property path '" + tokens.canonicalName + "'", ex);}}}//注入map类型的属性值else if (propValue instanceof Map) {//获取map集合key的类型Class<?> mapKeyType = ph.getMapKeyType(tokens.keys.length);//获取map集合value的类型Class<?> mapValueType = ph.getMapValueType(tokens.keys.length);Map<Object, Object> map = (Map<Object, Object>) propValue;// IMPORTANT: Do not pass full property name in here - property editors// must not kick in for map keys but rather only for map values.TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(mapKeyType);//解析map类型属性key值Object convertedMapKey = convertIfNecessary(null, null, lastKey, mapKeyType, typeDescriptor);Object oldValue = null;if (isExtractOldValueForEditor()) {oldValue = map.get(convertedMapKey);}// Pass full property name and old value in here, since we want full// conversion ability for map values.//解析map类型属性value值Object convertedMapValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),mapValueType, ph.nested(tokens.keys.length));//将解析后的key和value值赋值给map集合属性map.put(convertedMapKey, convertedMapValue);}else {throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,"Property referenced in indexed property path '" + tokens.canonicalName +"' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");}
}

通过对上面注入依赖代码的分析,我们已经明白了 Spring IOC 容器是如何将属性的值注入到 Bean 实例对象中去的:
1)、对于集合类型的属性,将其属性值解析为目标类型的集合后直接赋值给属性。
2)、对于非集合类型的属性,大量使用了 JDK 的反射机制,通过属性的 getter()方法获取指定属性注入以前的值,同时调用属性的 setter()方法为属性设置注入后的值。看到这里相信很多人都明白了 Spring的 setter()注入原理。

至此 Spring IOC 容器对 Bean 定义资源文件的定位,载入、解析和依赖注入已经全部分析完毕,现在Spring IOC 容器中管理了一系列靠依赖关系联系起来的 Bean,程序不需要应用自己手动创建所需的对象,Spring IOC 容器会在我们使用的时候自动为我们创建,并且为我们注入好相关的依赖,这就是Spring 核心功能的控制反转和依赖注入的相关功能。

一步一步手绘Spring DI运行时序图(Spring 自动装配之依赖注入)相关推荐

  1. 一步一步手绘Spring MVC运行时序图(Spring MVC原理)

    相关内容: 架构师系列内容:架构师学习笔记(持续更新) 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程) 一步一步手绘Spring IOC运行时序图二(基于XM ...

  2. 一步一步手绘Spring AOP运行时序图(Spring AOP 源码分析)

    相关内容: 架构师系列内容:架构师学习笔记(持续更新) 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程) 一步一步手绘Spring IOC运行时序图二(基于XM ...

  3. 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程)

    相关内容: 架构师系列内容:架构师学习笔记(持续更新) 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程) 一步一步手绘Spring IOC运行时序图二(基于XM ...

  4. 一步一步手绘Spring IOC运行时序图三(基于Annotation的IOC容器初始化)

    相关内容: 架构师系列内容:架构师学习笔记(持续更新) 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程) 一步一步手绘Spring IOC运行时序图二(基于XM ...

  5. 一步一步手绘Spring IOC运行时序图二(基于XML的IOC容器初始化)

    相关内容: 架构师系列内容:架构师学习笔记(持续更新) 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程) 一步一步手绘Spring IOC运行时序图二(基于XM ...

  6. 一步一步手绘Spring MVC运行时序图

    Spring MVC 初体验 初探Spring MVC 请求处理流程 Spring MVC 相对于前面的章节算是比较简单的,我们首先引用<Spring in Action>上 的一张图来了 ...

  7. 21.手绘Spring IOC运行时序图

    1.再谈IOC与 DI IOC(lnversion of Control)控制反转:所谓控制反转,就是把原先我们代码里面需要实现的对象创 建.依赖的代码,反转给容器来帮忙实现.那么必然的我们需要创建一 ...

  8. Spring框架—③依赖注入DI、Bean作用域及自动装配

    依赖注入 DI,Dependency injection 依赖: 指bean对象的创建依赖于Spring容器 注入: 指Bean对象所依赖的资源,由容器来设置和装配 在beans.xml中配置 1.常 ...

  9. 聊城大学计算机学院宿舍,聊城大学一学子巧售手绘明信片网络走红(组图)

    齐鲁晚报聊城11月6日讯(记者 王传胜)聊城大学宏伟壮观的南大门你见过吗?该校一名大三学生突发奇想,把包括南大门在内的八个校园场景制作成手绘明信片,上传到网上之后迅速走红."双十一" ...

最新文章

  1. Linux下运行.cpp文件
  2. python—函数进阶-迭代器
  3. 成功解决Error:invalid character in identifier
  4. Arcgis10 server安装
  5. jmu-python-函数-找钱_python函数题 - osc_wv1mxwu2的个人空间 - OSCHINA - 中文开源技术交流社区...
  6. (1)ActivityThread分析
  7. 知乎上的44条神回复,针针见血,看完整个人通透多了
  8. lua 面向对象入门
  9. 前后端分离项目,标准json协议格式参考
  10. oracle存储过程(PL/SQL)
  11. 步步为营-45-一套增删查改
  12. ImportError: DLL load failed while importing win32file
  13. Python实现决策树2(CART分类树及CART回归树)
  14. dell服务器开启64位支持,dell服务器虚拟化开启(戴尔bios设置虚拟化)
  15. 安装miktex+winedit
  16. 软件项目技术路线图_创建基本的项目路线图
  17. 看漫画学焊接!5分钟教你电烙铁的焊接方法
  18. 蓝桥杯的比赛流程和必考点
  19. 七、系统架构 - 伸缩性架构设计
  20. 【技术分享】Android App常见安全问题演练分析系统-DIVA-Part1

热门文章

  1. 路由器截获微信消息_小白智慧微信小程序无法打印的解决方案
  2. Linux下一些简单命令的收集
  3. mysql主从中异步和半同步的区别
  4. Struts1.x系列教程(16):使用LocaleAction类实现国际化的Web程序
  5. 对字符串进行加密解密
  6. SpringAOP 通知(adivce)- methodIntercepor
  7. TechEd2011之游园录(3)
  8. Word 2007批注及批注者姓名修改技巧
  9. 数据库链、物化视图、高级复制方面
  10. 2021奥斯汀 Pwn2Own黑客大赛落幕,Master of Pwn 诞生