`

Spring IOC源码-bean加载

阅读更多
1、装载bean的第一步,调用doGetBean(name,...)方法
(1)转换对应的beanName,参数里面的name未必是beanName,可能是别名或者factoryBean
(2)首先尝试从缓存中加载单例
(3)如果从缓存中拿到了bean,调用getObjectForBeanInstance 将bean实例化 
(4)原型模式依赖检查
(5)通过getParentBeanFactory获取parentBeanFactory
(6)获取RootBeanDefinition
(7)针对不同的scope进行bean的创建
(8)类型转换

 
2、从缓存中获取单例对象,其中,
singletonObjects是一个map,存储实例化后的对象
earlySingletonObjects也是一个map,存储实例化后的对象,与singletonObjects的区别是,当一个单例的bean被放到这个map中以后,当bean还在创建中的时候就可以通过getbean获取到了,用来检测循环引用
singletonFactories:保存beanName和创建bean的工厂之间的映射关系
registeredSingletons:保存当前所有已经注册的bean


 

 
3、根据不同的scope创建bean, 以单例为例:getSingleton()方法的第一个参数是beanName, 第二个参数是一个接口:ObjectFactory,这个接口提供一个getObject方法在getSingleton中的singletonObject = singletonFactory.getObject();时候使用。
下面看getObject的时候都做了什么
getObject会使用AbstractBeanFactory类的抽象方法:
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)  throws BeanCreationException;
他的实现写在AbstractAutowireCapableBeanFactory里面,继承结构图如下:



 
 
4、createBean进去以后首先找到BeanDefinition,然后调用doCreateBean()创建真正的bean,doCreateBean中完成了以下几件事:
(1)如果需要创建的bean是单例,需要首先清除缓存
(2)实例化bean,调用createBeanInstance()方法,将beanDefinition转化为BeanWrapper
这个过程包含以下几个步骤
  • 如果存在工厂方法,则使用工厂方法进行初始化
  • 当一个类有多个构造函数的时候,每个构造函数都有不同的参数,需要根据参数锁定构造函数并进行初始化
  • 如果即不存在工厂方法,也不存在带有参数的构造方法,使用默认构造方法进行bean的实例、
(3)调用populateBean进行属性的填充
(4)调用registerDisposableBeanIfNecessary进行bean的注册
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args); //创建beanWrapper
        }
        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
        Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
 
        // Allow post-processors to modify the merged bean definition.
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                mbd.postProcessed = true;
            }
        }
 
        // Eagerly cache singletons to be able to resolve circular references
        // even when triggered by lifecycle interfaces like BeanFactoryAware.
        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, 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) {
                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);
            }
        }
......
 
        // Register bean as disposable.
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd); //注册bean
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }
 
        return exposedObject;
    }
5、使用createBeanInstance创建bean实例
获取beanName对应的class
  • 如果存在工厂方法,使用工厂方法执行bean的初始化策略
  • 解析构造函数并进行构造函数的实例化
里面比较重要的方法是
autowireConstructor(beanName, mbd, null, null);(调用带有参数的构造方法)和instantiateBean(beanName, mbd);(调用无参构造方法)
6、使用populateBean进行属性注入
该方法中最重要的是对autowireByName(beanName, mbd, bw, newPvs);和对autowireByType(beanName, mbd, bw, newPvs);方法的调用,
最后再使用applyPropertyValues(beanName, mbd, bw, pvs);  将所有的属性填充到BeanWrapper中
 
 
 
 
(4)getBean方法中无论是要创建那种类型的bean最终都是通过getObjectForBeanInstance(...)方法生成,该方法是beanFactory与factoryBean的桥梁,在这个方法中调用BeanFactory通过factoryBean去创建bean
 
protected Object getObjectForBeanInstance(
            Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
 
        // Don't let calling code try to dereference the factory if the bean isn't a factory.
       //如果bean不是一个FactoryBean则不做任何处理
        if (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.
        if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
            return beanInstance;
        }
 
        Object object = null;
        if (mbd == null) {
            object = getCachedObjectForFactoryBean(beanName);
        }
        if (object == null) {
            // Return bean instance from factory.
            FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
            // Caches object obtained from FactoryBean if it is a singleton.
            if (mbd == null && containsBeanDefinition(beanName)) {
                mbd = getMergedLocalBeanDefinition(beanName);
            }
            boolean synthetic = (mbd != null && mbd.isSynthetic());
            object = getObjectFromFactoryBean(factory, beanName, !synthetic);
        }
        return object;
    }
(3)getObjectFromFactoryBean
 
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
        if (factory.isSingleton() && containsSingleton(beanName)) {
            synchronized (getSingletonMutex()) {
                Object object = this.factoryBeanObjectCache.get(beanName);
                if (object == null) {
                    object = doGetObjectFromFactoryBean(factory, beanName);
                    // Only post-process and store if not put there already during getObject() call above
                    // (e.g. because of circular reference processing triggered by custom getBean calls)
                    Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                    if (alreadyThere != null) {
                        object = alreadyThere;
                    }
                    else {
                        if (object != null && shouldPostProcess) {
                            try {
                                object = postProcessObjectFromFactoryBean(object, beanName);
                            }
                            catch (Throwable ex) {
                                throw new BeanCreationException(beanName,
                                        "Post-processing of FactoryBean's singleton object failed", ex);
                            }
                        }
                        this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
                    }
                }
                return (object != NULL_OBJECT ? object : null);
            }
        }
        else {
            Object object = doGetObjectFromFactoryBean(factory, beanName);
            if (object != null && shouldPostProcess) {
                try {
                    object = postProcessObjectFromFactoryBean(object, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
                }
            }
            return object;
        }
    }
(4)doGetObjectFromFactoryBean
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
            throws BeanCreationException {
 
        Object object;
        try {
            if (System.getSecurityManager() != null) {
                AccessControlContext acc = getAccessControlContext();
                try {
                    object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                        @Override
                        public Object run() throws Exception {
                                return factory.getObject();
                            }
                        }, acc);
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                object = factory.getObject();
            }
        }
        catch (FactoryBeanNotInitializedException ex) {
            throw new BeanCurrentlyInCreationException(beanName, ex.toString());
        }
        catch (Throwable ex) {
            throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
        }
 
        // Do not accept a null value for a FactoryBean that's not fully
        // initialized yet: Many FactoryBeans just return null then.
        if (object == null && isSingletonCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(
                    beanName, "FactoryBean which is currently in creation returned null from getObject");
        }
        return object;
    }
  • 大小: 77.7 KB
  • 大小: 29 KB
  • 大小: 90.2 KB
  • 大小: 46.3 KB
  • 大小: 30.6 KB
分享到:
评论

相关推荐

    Spring IoC源码深度剖析开源架构源码2021.pdf

    标题《Spring IoC源码深度剖析开源架构源码2021.pdf》和描述《Spring IoC源码深度剖析开源架构源码2021.pdf》表明该文档主要面向于分析Spring框架中控制反转(IoC)容器的核心源码,解析和理解其内部的工作机制及...

    spring-security-web源码所需jar包

    1. **spring-context-3.1.2.RELEASE.jar**:提供Spring的IoC(Inversion of Control)容器和AOP(Aspect Oriented Programming)支持,这是Spring框架的基础,为Spring Security提供了配置和事件处理能力。...

    Spring IOC源码解读

    Spring IOC,即Inversion of Control(控制反转),是Spring框架的核心特性之一,它负责管理和装配应用程序中的对象。...理解并掌握Spring的IOC源码,对于深入学习Spring框架以及提升系统设计能力具有重要意义。

    Spring ioc源码解读

    ### Spring IoC源码解读 #### 一、Spring IoC 容器概述 Spring框架的核心功能之一便是依赖注入(Dependency Injection, DI),而这一功能主要通过IoC容器来实现。在Spring框架中,IoC容器负责管理应用对象的生命...

    spring-framework-master

    "spring-framework-master"这一压缩包包含了Spring框架的完整源码,为我们提供了深入理解这一强大工具的绝佳机会。 Spring的核心设计理念是依赖注入(Dependency Injection,简称DI),它通过反转控制(Inversion ...

    Spring Ioc源码分析系列--自动注入循环依赖的处理.doc

    Spring Ioc 源码分析系列--自动注入循环依赖的处理 本篇文章主要讲解了 Spring Ioc 源码分析系列中自动注入循环依赖的处理机制。循环依赖是 Spring 框架中一个经典的问题,也是面试中常被问到的问题。本篇文章将...

    官方原版源码spring-framework-5.1.4.RELEASE.zip

    例如,关于IoC(Inversion of Control,控制反转)的实现,Spring使用了XML配置或注解来定义bean的依赖关系,通过反射机制动态加载和管理bean。另外,AOP模块实现了切面编程,允许我们定义横切关注点,如日志、事务...

    官方源码 spring-framework-5.3.2.zip

    Spring的IoC(Inversion of Control)容器和AOP(Aspect-Oriented Programming)支持在5.3.2中得到加强,包括对Java配置的优化,以及对注解的更精细控制。此外,还增强了Bean生命周期管理,如条件化 Bean 的创建和...

    spring源码spring-framework-4.3.2.RELEASE

    通过XML配置或注解方式定义bean,IoC容器负责实例化、装配和管理这些bean。 2. **AOP(Aspect Oriented Programming)**:Spring的AOP模块实现了面向切面编程,允许开发者定义方法拦截器和切入点表达式,用于代码的...

    spring-framework-1.0-m1.zip源码

    1. ApplicationContext:在Spring 1.0中,ApplicationContext是主要的上下文接口,负责加载配置文件,管理Bean,并提供事件发布等功能。它是所有其他Spring服务的基础。 2. BeanFactory:作为ApplicationContext的...

    官方原版源码spring-framework-5.2.3.RELEASE.zip

    《Spring Framework 5.2.3源码深度解析》 Spring Framework是Java开发中的核心框架,它为构建高质量的应用提供了全面的基础设施。5.2.3版本是Spring的一个稳定版本,包含了众多改进和新特性。这个官方原版源码包为...

    基于Maven构建的Spring IoC源码实例

    在"基于Maven构建的Spring IoC源码实例"中,我们可以学到如何使用Maven搭建Spring项目,并通过Spring IoC实现组件间的依赖注入。以下是这个实例中可能包含的关键知识点: 1. **Maven项目结构**:了解标准的Maven...

    Spring Ioc源码分析系列--@Autowired注解的实现原理.doc

    Spring Ioc源码分析系列--@Autowired注解的实现原理 @ Автоwired注解是 Spring Framework 中的一个重要组件,它提供了自动装配的功能,能够将 Bean 之间的依赖关系自动解析和注入。今天,我们将深入探讨 @...

    官方原版完整包 spring-framework-5.3.1.RELEASE.zip

    2. **spring-beans**: 支持Bean工厂和XML配置,是IoC容器实现的基础。 3. **spring-context**: 扩展了IoC容器,引入了上下文概念,提供了对国际化、事件、资源、缓存等支持。 4. **spring-aop**: 实现了面向切面...

    spring3.2源码-官方原版.zip

    在Spring 3.2源码中,你还可以探索到IoC容器的实现,包括Bean的创建、初始化、作用域管理以及依赖解析的细节;AOP代理的生成,包括JDK动态代理和CGLIB代理的使用;还有Spring对各种协议(如JMS、JMX)的支持,以及...

    spring-framework-bom源码

    在源码中,我们可以找到关于BeanFactory和ApplicationContext的实现,理解它们如何加载配置、实例化和管理Bean。 4. **AOP(面向切面编程)**:Spring的AOP模块支持声明式事务管理和其他横切关注点,如日志记录、...

    Java进阶之SpringIoC源码深度剖析共19页.pd

    【标题】"Java进阶之SpringIoC源码深度剖析共19页.pd" 提供的是一项关于Java开发中的高级主题,特别是针对Spring框架的依赖注入(Inversion of Control,IoC)部分的深入研究。Spring IoC是Spring框架的核心特性之一...

    官方原版源码 spring-framework-5.1.15.RELEASE.zip

    Spring Core负责基础的IoC(Inversion of Control)容器,Spring Beans则实现了Bean的生命周期管理和配置,Spring Context则是基于Core之上构建的,提供了一个应用上下文,可以管理Bean并与其他Spring模块集成。...

    【框架源码篇 01】Spring源码-手写IOC

    通过分析和手写Spring的IOC源码,我们可以更好地理解Spring的工作原理,从而更有效地利用它来构建我们的应用程序。在01-手写IoC源码-spring-v1.zip文件中,你将找到逐步实现这个过程的代码示例,这将帮助你加深对...

    spring学习----工厂Bean

    在Spring框架中,"工厂Bean"是一个非常关键的概念,它扩展了传统的Bean定义,使得我们可以在Spring IoC容器中创建自定义的实例化逻辑。工厂Bean允许开发者在对象实例化时进行更复杂的控制,比如引入特定的初始化过程...

Global site tag (gtag.js) - Google Analytics