bean的构建(一)

简介: bean的构建

bean的构建

  1. createBean调用堆栈
  2. 基本思路如下:
  1. beanName的转换
  2. 从缓存中加载单例bean
  3. 对bean进行实例化
  4. 原型模式检查
  5. BeanDefinition转化为RootBeanDefinition
  6. 加载bean的依赖
  7. 针对不同的域进行bean的创建
  8. bean的类型转换
  • doGetBean总纲:
  • 获取bean:
  • 合并bean定义:
  • 获取当前bean的依赖:
  • 创建Bean:

doGetBean

protected<T> T doGetBean(
        String name,@Nullable Class<T> requiredType,@Nullable Object[]args,boolean typeCheckOnly)
        throws BeansException{
        //对于beanName的转换
        //因为可能会存在FactoryBean或者bean的别名指向别的bean
        String beanName=transformedBeanName(name);
        Object bean;
        //此处解决了单例bean的循环依赖问题,提前暴露了bean的ObjectFactory或者bean本身,
        // 如果其余bean存在依赖,则直接获取,从而解决了循环依赖
        //从缓存或者ObjectFactory中获取bean实例
        Object sharedInstance=getSingleton(beanName);
        //如果可以从缓存中或者ObjectFactory中获取beanInstance
        if(sharedInstance!=null&&args==null){
        if(logger.isTraceEnabled()){
        if(isSingletonCurrentlyInCreation(beanName)){
        logger.trace("Returning eagerly cached instance of singleton bean '"+beanName+
        "' that is not fully initialized yet - a consequence of a circular reference");
        }
        else{
        logger.trace("Returning cached instance of singleton bean '"+beanName+"'");
        }
        }
        //对bean类型的检测;bean可能为空,bean可能是以&开头的FactoryBean,也可能是仿造FactoryBean的错误Bean
        bean=getObjectForBeanInstance(sharedInstance,name,beanName,null);
        }
        //如果不能从缓存中或者ObjectFactory中获取beanInstance
        else{
        //Spring只会解决单例bean的循环依赖(因为原型bean无法保存bean的状态,以至于无法提前暴露bean),
        //如果存在原型的循环依赖,则显示抛出异常
        if(isPrototypeCurrentlyInCreation(beanName)){
        throw new BeanCurrentlyInCreationException(beanName);
        }
        // Check if bean definition exists in this factory.
        //获取父级beanFactory
        BeanFactory parentBeanFactory=getParentBeanFactory();
        //如果父级beanFactory不为空,且自身BeanDefinition的Map集合不包含key为beanName的key
        if(parentBeanFactory!=null&&!containsBeanDefinition(beanName)){
        //自身没有key为beanName的key,则查找父级beanFactory(parentBeanFactory)
        //获取bean的名称,主要是区分普通Bean以及FactoryBean
        String nameToLookup=originalBeanName(name);
        //递归查询bean并且返回bean的instance
        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 if(requiredType!=null){
        // No args -> delegate to standard getBean method.
        return parentBeanFactory.getBean(nameToLookup,requiredType);
        }
        else{
        return(T)parentBeanFactory.getBean(nameToLookup);
        }
        }
        if(!typeCheckOnly){
        markBeanAsCreated(beanName);
        }
        try{
        //将子bean定义以及父bean定义合并,并且转化为RootBeanDefinition
        RootBeanDefinition mbd=getMergedLocalBeanDefinition(beanName);
        //检查BeanDefinition必须非抽象,如果是抽象,则直接抛出异常
        checkMergedBeanDefinition(mbd,beanName,args);
        //获取当前bean所依赖的bean,先实例化自身依赖的bean
        String[]dependsOn=mbd.getDependsOn();
        //如果自身bean存在依赖bean
        if(dependsOn!=null){
        for(String dep:dependsOn){
        //确定指定的依赖 bean 是否已注册为依赖于给定 bean 或其任何传递依赖项
        //确定自身bean是否已经注册为自身bean的任何依赖项;如果已经注册,则认为当前bean依赖于自身,存在循环依赖
        //否则注册自身所依赖的bean
        if(isDependent(beanName,dep)){
        throw new BeanCreationException(mbd.getResourceDescription(),beanName,
        "Circular depends-on relationship between '"+beanName+"' and '"+dep+"'");
        }
        //缓存中注册自身所依赖的所有bean
        registerDependentBean(dep,beanName);
        try{
        //递归创建自身所依赖的bean
        getBean(dep);
        }
        catch(NoSuchBeanDefinitionException ex){
        throw new BeanCreationException(mbd.getResourceDescription(),beanName,
        "'"+beanName+"' depends on missing bean '"+dep+"'",ex);
        }
        }
        }
        // 创建bean的实例
        // 创建bean->初始化bean
        if(mbd.isSingleton()){
        sharedInstance=getSingleton(beanName,()->{
        try{
        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.
        destroySingleton(beanName);
        throw ex;
        }
        });
        bean=getObjectForBeanInstance(sharedInstance,name,beanName,mbd);
        }
        else if(mbd.isPrototype()){
        // It's a prototype -> create a new instance.
        Object prototypeInstance=null;
        try{
        beforePrototypeCreation(beanName);
        prototypeInstance=createBean(beanName,mbd,args);
        }
        finally{
        afterPrototypeCreation(beanName);
        }
        bean=getObjectForBeanInstance(prototypeInstance,name,beanName,mbd);
        }
        else{
        String scopeName=mbd.getScope();
        if(!StringUtils.hasLength(scopeName)){
        throw new IllegalStateException("No scope name defined for bean ´"+beanName+"'");
        }
        Scope scope=this.scopes.get(scopeName);
        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=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.
        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.isTraceEnabled()){
        logger.trace("Failed to convert bean '"+name+"' to required type '"+
        ClassUtils.getQualifiedName(requiredType)+"'",ex);
        }
        throw new BeanNotOfRequiredTypeException(name,requiredType,bean.getClass());
        }
        }
        return(T)bean;
        }
目录
相关文章
|
Java 定位技术 uml
每日一博 - 探索代码世界的地图 code iris
每日一博 - 探索代码世界的地图 code iris
314 0
|
12月前
|
Java Linux 测试技术
JMeter的运行
JMeter是一款基于Java的压力测试工具,适用于Windows、Mac及Linux系统。运行JMeter需Java 8及以上版本,建议至少1GB内存。用户可通过双击bin目录下的jmeter.bat/.sh文件或命令行启动。其主界面包括文件、编辑、查找、运行、选项与帮助等菜单,支持测试计划的创建、编辑与执行,并提供详细的帮助文档。正确配置环境变量可简化启动流程。
|
存储 供应链 算法
深入理解Java中的ConcurrentSkipListMap:高效并发的有序映射
深入理解Java中的ConcurrentSkipListMap:高效并发的有序映射
|
存储 NoSQL 前端开发
MongoDB——副本集与分片
 MongoDB复制是将数据同步在多个服务器的过程。
1034 0
MongoDB——副本集与分片
|
消息中间件 Kafka 测试技术
【Kafka揭秘】Leader选举大揭秘!如何打造一个不丢失消息的强大Kafka集群?
【8月更文挑战第24天】Apache Kafka是一款高性能分布式消息系统,利用分区机制支持数据并行处理。每个分区含一个Leader处理所有读写请求,并可有多个副本确保数据安全与容错。关键的Leader选举机制保障了系统的高可用性和数据一致性。选举发生于分区创建、Leader故障或被手动移除时。Kafka提供多种选举策略:内嵌机制自动选择最新数据副本为新Leader;Unclean选举快速恢复服务但可能丢失数据;Delayed Unclean选举则避免短暂故障下的Unclean选举;Preferred选举允许基于性能或地理位置偏好指定特定副本为首选Leader。
288 5
|
机器学习/深度学习 网络协议 算法
IGP高级特性(一)
IGP高级特性(一)
|
JavaScript 前端开发 C++
打造卓越 QML 层级设计:从入门到精通(二)
打造卓越 QML 层级设计:从入门到精通(二)
1468 0
|
Java 测试技术 Maven
JUnit5学习之五:标签(Tag)和自定义注解
学习和实践JUnit5的标签过滤和自定义注解功能
224 1
JUnit5学习之五:标签(Tag)和自定义注解
|
存储 数据可视化 开发工具
深入了解Git:介绍及常用命令指南
Git是一种分布式版本管理系统(版本管理就是管理更新的历史记录。它为我们提供了一些在软件开发过程中必不可少的功能,例如记录一款软件添加或更改源代码的过程,回滚到特定阶段,恢复误删除的文件等。),由Linus Torvalds于2005年创造,旨在帮助开发人员更好地协同工作和管理代码。与集中式版本控制系统(如SVN)不同,Git将代码存储在本地仓库中,使每个开发人员都能在自己的计算机上拥有完整的项目副本,并可以独立地进行开发、测试和修改。
494 1
深入了解Git:介绍及常用命令指南
|
存储 大数据
大数据数据存储的分布式文件系统的HDFS的核心机制理解的数据复制和原理
在 Hdfs 中,数据的复制和原理是基于块的分布式存储。
204 1