spring ioc容器之Bean实例化和依赖注入

     spring中的bean对象和java对象是有些许差别的,spring中的bean包含了java对象,并且是基于java对象在spring中做了一些列的加工,所以说spring中的bean比java对象更加丰富。在spring中bean的实例化有2个时机:

  • spring ioc容器初始化的时候,需要预实例化的单例bean。
  • 初次调用getBean方法的时候,会触发bean的实例化。
注:spring中的单例bean并不是说容器中这个类的bean实例只能有一个,他和单例模式是有区别的。在spring容器中,单例bean是指类型相同并且同名的实例在同一个spring容器中只允许有一个bean实例。

     下面从spring ioc容器初始化的时候,预实例化的bean为线索来追溯bean的实例化和依赖注入过程,这个过程涵盖了getBean方法。

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // ...
            try {
                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);
            }
            catch (BeansException ex) {
                // ...
            }
        }
}

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // ...

        // Instantiate all remaining (non-lazy-init) singletons.
        beanFactory.preInstantiateSingletons();
}

public void preInstantiateSingletons() throws BeansException {

        //这里根据注册的所有BeanDefinition信息来遍历预实例化所有的bean信息
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            //预实例化的条件:非抽象、单例和非懒加载的bean
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(new PrivilegedAction() {
                            @Override
                            public Boolean run() {
                                return ((SmartFactoryBean) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
                else {
                    getBean(beanName);
                }
            }
        }
}

     在spring ioc容器初始化的时候,触发了所有预实例化的bean的加载,这里必须是非抽象、单例和非懒加载的bean才符合条件进行预实例化。具体bean的实例化是在getBean方法中。

public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

protected  T doGetBean(
            final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
            throws BeansException {

        final String beanName = transformedBeanName(name);
        Object bean;

        //从缓存中获取bean实例,对于实例化了的bean对象,直接从容器缓存中获取
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == 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 = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        // ...
        return (T) bean;
}

     这里通过getSingleton先从缓存中获取bean实例。

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        //从spring容器一级缓存中获取bean实例
        Object singletonObject = this.singletonObjects.get(beanName);
        //如果一级缓存中没有,并且bean实例是在创建中(循环依赖)
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                //从二级缓存中获取,为解决bean的循环依赖添加了二级缓存
                singletonObject = this.earlySingletonObjects.get(beanName);
                //如果二级缓存中为空,则从三级缓存中获取bean实例
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
                    //如果三级缓存不为空的时候,这里会去从三级缓存中获取bean实例,这里的bean有可能是已经完成的aop的代理对象,在解决循环依赖的时候会添加上,提前进行aop操作
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

     从缓存中获取很好理解,分别从spring容器的一级缓存singletonObjects、二级缓存earlySingletonObjects和三级缓存singletonFactories中获取bean实例。在初次获取bean的时候,这里的缓存肯定为空的,但是对于存在循环依赖的bean,这里的一级或二级缓存就不是空的。在有循环依赖的bean中,这里一级缓存会存在不为空的情况,这个时候通过singletonFactory.getObject的时候,返回的可能是一个bean实例,也有可能是一个提前进行aop的代理对象(正常情况下aop是发生在bean初始化的时候完成的),对于有循环依赖并且需要进行aop的bean,在这里会进行提前aop代理对象的生成。

protected  T doGetBean(
            final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
            throws BeansException {

        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            // ...
        }

        else {
            
            //这里把bean添加到集合中,标记为正在创建中
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

            try {
                //当前bean依赖的bean提前先进行实例化,这里和属性的依赖注入不是一个东西
                String[] dependsOn = mbd.getDependsOn();
                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 + "'");
                        }
                        registerDependentBean(dep, beanName);
                        try {
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                // Create bean instance.
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, new ObjectFactory() {
                        @Override
                        public Object getObject() throws BeansException {
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            catch (BeansException ex) {
                                destroySingleton(beanName);
                                throw ex;
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                
                // ...
            }
        }

        // ...
        return (T) bean;
    }

     当缓存中没有找到bean实例的时候:

  • 先把bean添加到alreadyCreated集合中,标记当前bean正在创建中(为循环依赖做前置判断准备),
  • 对于当前bean存在依赖dependsOn的bean,提前在当前bean前进行实例化(这里的dependsOn依赖的bean和属性依赖注入不是一个东西,两者是有区别的)。
  • 在BeanDefinition中定义的当前bean是单例的时候,通过getSingleton方法去获取bean实例,这里是通过回调createBean去获取的bean实例。
public Object getSingleton(String beanName, ObjectFactory singletonFactory) {
        synchronized (this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                
                try {
                    //这里回调的是前面添加的ObjectFactory
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                
                //获取的是新创建的bean实例,添加到spring容器的一级缓存singletonObjects中
                if (newSingleton) {
                    addSingleton(beanName, singletonObject);
                }
            }
            return (singletonObject != NULL_OBJECT ? singletonObject : null);
        }
}

     通过singletonFactory.getObject回调前面的createBean方法获取bean实例,然后对于是新创建的bean实例添加到spring容器中的一级缓存singletonObjects中。下面从createBean中看bean是如何实例化的。

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
        
        // ...

        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
}

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
            throws BeanCreationException {

        //这里完成bean的创建过程,这里创建的是一个java对象,并把它包装到instanceWrapper中
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }

        //对于单例并且是正在创建中的bean,为解决循环依赖,添加一个ObjectFactory到三级缓存singletonFactories中,为后续创建bean实例做准备
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            //添加一个ObjectFactory到三级缓存中,这里可能会去生成一个aop代理对象
            addSingletonFactory(beanName, new ObjectFactory() {
                @Override
                public Object getObject() throws BeansException {
                    return getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            //这里去进行依赖注入
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
                //bean的初始话
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
        }

        
        return exposedObject;
}

    在这里可以看到整个bean实例化的全貌,也可以看出bean在spring中的生命周期:

  • createBeanInstance创建一个bean对象,这个对象是一个干净的java对象
  • earlySingletonExposure对于单例正在创建的bean,为解决循环依赖,添加一个ObjectFactory到spring容器的三级缓存中,在后面解决循环依赖的时候用到。
  • populateBean设置bean的属性,也就是在这里完成bean的依赖注入,递归地进行bean的实例化。
  • initializeBean初始化bean,执行bean的初始化方法,以及相应的后置处理器。

创建bean实例的方法createBeanInstance看看bean的具体创建的方式:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {

    //实例化bean
    return instantiateBean(beanName, mbd);
}

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    
    // ...

    //实例化bean
    beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
    BeanWrapper bw = new BeanWrapperImpl(beanInstance);
    initBeanWrapper(bw);
    return bw;
}


public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
        //这里是根据BeanDefinition中方法是否有重写或增强来判断是用反射还是cglib来进行对象的创建
        if (bd.getMethodOverrides().isEmpty()) {
            // ...

            //根据反射创建bean
            return BeanUtils.instantiateClass(constructorToUse);
        }
        else {
            //使用cglib创建bean
            return instantiateWithMethodInjection(bd, beanName, owner);
        }
}

     可以看到在spring中是通过SimpleInstantiationStrategy类来进行bean对象的创建,有java反射和cglib两种方式进行bean的创建,判断依据是,在BeanDefinition中有动态代理或增强的时候会用cglib去创建bean对象。

earlySingletonExposure解决循环依赖

     根据bean是单例,并且当前bean是在创建中的时候,会去添加一个ObjectFactory到spring容器的三级缓存singletonFactories中。这里会有可能提前进行aop代理对象的生成。

//对于单例并且是正在创建中的bean,为解决循环依赖,添加一个ObjectFactory到三级缓存singletonFactories中,为后续创建bean实例做准备
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            //添加一个ObjectFactory到三级缓存中,这里可能会去生成一个aop代理对象
            addSingletonFactory(beanName, new ObjectFactory() {
                @Override
                public Object getObject() throws BeansException {
                    return getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
        Object exposedObject = bean;
        if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                    //这里执行后置处理器的方法
                    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                    if (exposedObject == null) {
                        return null;
                    }
                }
            }
        }
        return exposedObject;
}

//在AbstractAutoProxyCreator中如果有代理对象会进行aop代理对象的生成
public Object getEarlyBeanReference(Object bean, String beanName) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        this.earlyProxyReferences.put(cacheKey, bean);
        return wrapIfNecessary(bean, beanName, cacheKey);
}

     这里把一个ObjectFactory添加到spring容器的三级缓存中去,在前面通过缓存获取bean的时候,会执行这里的getEarlyBeanReference方法,在这个方法中会去执行一些后置处理器的方法。AbstractAutoProxyCreator会生成一个代理对象,这里就是提前进行了aop代理对象的生成。

populateBean设置bean的属性,进行属性的依赖注入
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
        PropertyValues pvs = mbd.getPropertyValues();
        // ...

        if (hasInstAwareBpps || needsDepCheck) {
            PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            if (hasInstAwareBpps) {
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                        //这里去执行一些后置处理器,譬如@Autowired就是在这里产生作用的
                        pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvs == null) {
                            return;
                        }
                    }
                }
            }
            if (needsDepCheck) {
                checkDependencies(beanName, mbd, filteredPds, pvs);
            }
        }

        applyPropertyValues(beanName, mbd, bw, pvs);
}

     在这里会去执行一些后置处理器的postProcessPropertyValues方法,@Autowired注解的AutowiredAnnotationBeanPostProcessor就是在这里生效的。下面来看看AutowiredAnnotationBeanPostProcessor对属性依赖注入的处理

public PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {

        //获取所有被@Autowired注解修饰的属性
        InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
        try {
            //完成属性的依赖注入
            metadata.inject(bean, beanName, pvs);
        }
        catch (BeanCreationException ex) {
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
        }
        return pvs;
}
initializeBean完成bean的初始化操作
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction() {
                @Override
                public Object run() {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
        return wrappedBean;
    }

  • invokeAwareMethods执行一些实现了Aware接口的方法,譬如:设置BeanName、classLoader和BeanFactory给当前bean
  • 执行后置处理器的postProcessBeforeInitialization方法
  • 执行bean的初始化方法,如果是实现了InitializeBean接口就调用afterPropertiesSet方法,否则就调用自定义的初始化方法。
  • 执行后置处理器的postProcessAfterInitialization方法
     在执行后置处理器的postProcessAfterInitialization方法时会生成aop代理对象。

     在执行后置处理器的postProcessAfterInitialization方法时,会去执行AbstractAutoProxyCreator类的postProcessAfterInitialization方法,这里会去根据需要生成当前bean的aop代理对象。

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }
     spring bean的生命周期:
  • 根据jdk反射或cglib生成Bean的java对象。
  • 调用populateBean设置bean的属性,这里会进行属性的依赖注入,会去生成依赖的所有bean的实例。
  • 执行BeanPostProcessor后置处理器的postProcessBeforeInitialization方法
  • 执行bean的初始化方法,可以是实现了InitializingBean接口的afterPropertiesSet,也可以是自定义的初始化方法。
  • 执行BeanPostProcessor后置处理器的postProcessAfterInitialization方法,这里会根据需要使用AbstractAutoProxyCreator来生成aop代理对象。

你可能感兴趣的:(spring ioc容器之Bean实例化和依赖注入)