spring源码解析-Bean的实例化

在上一章我们已经获取到了BeanDefinition,现在就可以开始对Bean进行实例化的操作了

Bean的实例化分为两种情况延迟加载和非延迟加载

这里只分析非延迟加载的情况

Bean的实例化操作是在AbstractApplicationContext#refresh中的finishBeanFactoryInitialization方法中进行

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 设置转换器
        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
            beanFactory.setConversionService(
                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
        }

        //省略部份代码

                // 处理代码织入
                String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }
        // 准备初始化非懒加载Bean
        beanFactory.preInstantiateSingletons();
    }

可以看出其中关键方法为preInstantiateSingletons

调用流程

spring源码解析-Bean的实例化_第1张图片
Bean实例化时序图

可以看出核心是instantiateBeanapplyPropertyValues方法

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
        try {
            Object beanInstance;
            final BeanFactory parent = this;
            if (System.getSecurityManager() != null) {
                beanInstance = AccessController.doPrivileged(new PrivilegedAction() {
                    @Override
                    public Object run() {
                    //策略模式默认调用CglibSubclassingInstantiationStrategy
                        return getInstantiationStrategy().instantiate(mbd, beanName, parent);
                    }
                }, getAccessControlContext());
            }
            else {
                beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
            }
            //BeanWrapper是实例Bean的再次包装
            BeanWrapper bw = new BeanWrapperImpl(beanInstance);
            initBeanWrapper(bw);
            return bw;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
        }
    }
 
 

再看SimpleInstantiationStrategy#instantiate(RootBeanDefinition, String,BeanFactory)方法

public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
        // Don't override the class with CGLIB if no overrides.
        if (bd.getMethodOverrides().isEmpty()) {
            Constructor constructorToUse;
            synchronized (bd.constructorArgumentLock) {
            //获取构造方法或者工厂方法
                constructorToUse = (Constructor) bd.resolvedConstructorOrFactoryMethod;
                if (constructorToUse == null) {
                    final Class clazz = bd.getBeanClass();
                    if (clazz.isInterface()) {
                        throw new BeanInstantiationException(clazz, "Specified class is an interface");
                    }
                    try {
                        if (System.getSecurityManager() != null) {
                            constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction>() {
                                @Override
                                public Constructor run() throws Exception {
                                    return clazz.getDeclaredConstructor((Class[]) null);
                                }
                            });
                        }
                        else {
                            constructorToUse =  clazz.getDeclaredConstructor((Class[]) null);
                        }
                        bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                    }
                    catch (Throwable ex) {
                        throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                    }
                }
            }
            //使用BeanUtils实例化,里面调用的是构造方法实例化
            return BeanUtils.instantiateClass(constructorToUse);
        }
        else {
        //CglibSubclassingInstantiationStrategy重写了该方法,使用cglib实例化
            return instantiateWithMethodInjection(bd, beanName, owner);
        }
    }

具体的cglib方法就不展开了,对象实例化之后还需要将其属性填充进去,并完成依赖关系的处理,这个过程叫依赖注入

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        if (pvs == null || pvs.isEmpty()) {
            return;
        }

        MutablePropertyValues mpvs = null;
        List original;

        if (System.getSecurityManager() != null) {
            if (bw instanceof BeanWrapperImpl) {
                ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
            }
        }

        if (pvs instanceof MutablePropertyValues) {
            mpvs = (MutablePropertyValues) pvs;
            if (mpvs.isConverted()) {
                // Shortcut: use the pre-converted values as-is.
                try {
                    bw.setPropertyValues(mpvs);
                    return;
                }
                catch (BeansException ex) {
                    throw new BeanCreationException(
                            mbd.getResourceDescription(), beanName, "Error setting property values", ex);
                }
            }
            original = mpvs.getPropertyValueList();
        }
        else {
            original = Arrays.asList(pvs.getPropertyValues());
        }
//自定义类型转换器
        TypeConverter converter = getCustomTypeConverter();
        if (converter == null) {
            converter = bw;
        }
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

        //创建副本用于转换及注入到Bean中
        List 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();
                //通过属性获取值,并处理依赖关系
                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();
        }

        // 参数注入的地方
        try {
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        }
        catch (BeansException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Error setting property values", ex);
        }
    }

处理依赖关系的方法BeanDefinitionValueResolver#resolveValueIfNecessary

public Object resolveValueIfNecessary(Object argName, Object value) {
        //如果该Bean被其它对象依赖时
        if (value instanceof RuntimeBeanReference) {
            RuntimeBeanReference ref = (RuntimeBeanReference) value;
            return resolveReference(argName, ref);
        }
        else if (value instanceof RuntimeBeanNameReference) {
            //省略源码
        }
        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) {
            //省略源码
            return resolveInnerBean(argName, innerBeanName, bd);
        }
        else if (value instanceof ManagedArray) {
            //省略源码
            return resolveManagedArray(argName, (List) value, elementType);
        }
        else if (value instanceof ManagedList) {
            // May need to resolve contained runtime references.
            return resolveManagedList(argName, (List) value);
        }
        else if (value instanceof ManagedSet) {
            // May need to resolve contained runtime references.
            return resolveManagedSet(argName, (Set) value);
        }
        else if (value instanceof ManagedMap) {
            // May need to resolve contained runtime references.
            return resolveManagedMap(argName, (Map) value);
        }
        else if (value instanceof ManagedProperties) {
            //省略源码
            return copy;
        }
        else if (value instanceof TypedStringValue) {
            //省略源码
        }
        else {
            return evaluate(value);
        }
    }

    private Object resolveInnerBean(Object argName, String innerBeanName, BeanDefinition innerBd) {
        RootBeanDefinition mbd = null;
        try {
            mbd = this.beanFactory.getMergedBeanDefinition(innerBeanName, innerBd, this.beanDefinition);
            // Check given bean name whether it is unique. If not already unique,
            // add counter - increasing the counter until the name is unique.
            String actualInnerBeanName = innerBeanName;
            if (mbd.isSingleton()) {
                actualInnerBeanName = adaptInnerBeanName(innerBeanName);
            }
            this.beanFactory.registerContainedBean(actualInnerBeanName, this.beanName);
            // 确保依赖的Bean已经被实例化
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                // 获取依赖的Bean,如果没有被创建该方法会自动创建
                for (String dependsOnBean : dependsOn) {
                    this.beanFactory.registerDependentBean(dependsOnBean, actualInnerBeanName);
                    this.beanFactory.getBean(dependsOnBean);
                }
            }
            //开始实例化Bean
            Object innerBean = this.beanFactory.createBean(actualInnerBeanName, mbd, null);
            if (innerBean instanceof FactoryBean) {
                boolean synthetic = mbd.isSynthetic();
                return this.beanFactory.getObjectFromFactoryBean(
                        (FactoryBean) innerBean, actualInnerBeanName, !synthetic);
            }
            else {
                return innerBean;
            }
        }
        catch (BeansException ex) {
            throw new BeanCreationException(
                    this.beanDefinition.getResourceDescription(), this.beanName,
                    "Cannot create inner bean '" + innerBeanName + "' " +
                    (mbd != null && mbd.getBeanClassName() != null ? "of type [" + mbd.getBeanClassName() + "] " : "") +
                    "while setting " + argName, ex);
        }
    }

参数注入
AbstractNestablePropertyAccessor#setPropertyValue(AbstractNestablePropertyAccessor.PropertyTokenHolder, PropertyValue)
方法比较长,就不贴了,主要是对集合类和非集合类的注入

对集合类

//如果是list类型
if (propValue instanceof List) {
                PropertyHandler ph = getPropertyHandler(actualName);
                Class requiredType = ph.getCollectionType(tokens.keys.length);
                List list = (List) propValue;
                int index = Integer.parseInt(key);
                Object oldValue = null;
                if (isExtractOldValueForEditor() && index < list.size()) {
                    oldValue = list.get(index);
                }
                //如果有对应参数转换器则将原值转换
                Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
                        requiredType, ph.nested(tokens.keys.length));
                int size = list.size();
                if (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 + propertyName,
                                    "Cannot set element with index " + index + " in List of size " +
                                    size + ", accessed using property path '" + propertyName +
                                    "': List does not support filling up gaps with null elements");
                        }
                    }
                    //如果超出原有长度,则新增数据
                    list.add(convertedValue);
                }
                else {
                //替换原有值
                    try {
                        list.set(index, convertedValue);
                    }
                    catch (IndexOutOfBoundsException ex) {
                        throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
                                "Invalid list index in property path '" + propertyName + "'", ex);
                    }
                }
            }

 
 

对非集合类org.springframework.beans.BeanWrapperImpl.BeanPropertyHandler#setValue方法使用反射注入参数

public void setValue(final Object object, Object valueToApply) throws Exception {
            final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
                    ((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
                    this.pd.getWriteMethod());
            if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) {
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged(new PrivilegedAction() {
                        @Override
                        public Object run() {
                            writeMethod.setAccessible(true);
                            return null;
                        }
                    });
                }
                else {
                    writeMethod.setAccessible(true);
                }
            }
            final Object value = valueToApply;
            if (System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged(new PrivilegedExceptionAction() {
                        @Override
                        public Object run() throws Exception {
                            writeMethod.invoke(object, value);
                            return null;
                        }
                    }, acc);
                }
                catch (PrivilegedActionException ex) {
                    throw ex.getException();
                }
            }
            else {
                writeMethod.invoke(getWrappedInstance(), value);
            }
        }
 
 

到这一步Bean的实例化就结束了

你可能感兴趣的:(spring源码解析-Bean的实例化)