美文网首页
spring ioc容器之Bean实例化和依赖注入

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

作者: 圣村的希望 | 来源:发表于2021-05-06 14:47 被阅读0次

         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<Boolean>() {
                                @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> T doGetBean(
                final String name, final Class<T> 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> T doGetBean(
                final String name, final Class<T> 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<Object>() {
                            @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<Object>() {
                    @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<Object>() {
                    @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<Object>() {
                    @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实例化和依赖注入

          本文链接:https://www.haomeiwen.com/subject/xytddltx.html