Dubbo源码学习(八)ScopeBeanFactory对比Spring 的BeanFactory

news2024/9/19 10:50:15

目录

1. ScopeBeanFactory与BeanFactory对比

2. 注册Bean

3. 执行一系列的PostProccessor


1. ScopeBeanFactory与BeanFactory对比

        ScopeBeanFactory是Dubbo自己定义的管理Bean的一个类, 类似于Spring  BeanFactory注册管理Bean的方式, 不同的是Spring BeanFactory是一个接口,主要实现是DefaultListableBeanFactory。 

        ScopeBeanFactory的设计思想类似于Spring 的BeanFactory, 对比如下:

Dubbo Spring其他
描述Bean的方式 BeanInfo对象BeanDefinition接口
有无父亲 包含parent, 在本类里定义。包含parent , BeanFactory, 在AbstractBeanFactory抽象类里定义。他们在getBean时都先找自己的,自己没有再找父亲的, 判断的时候如果自己没有,那么直接返回false, 因为父亲那儿也时基于儿子的。
存放容器 CopyOnWriteArrayList ConcurrentHashMap
初始化Bean后的操作 执行initializeBean方法,然后执行所有的ExtensionPostProccess Bean 初始化结束后在AbstractAutowireCapableBeanFactory类里applyBeanPostProceesorAfterInitialization(Object existingBean, String name)
PostProcessorExtensionAccessor接口提供了一系列的ExtensionPostProcessor在AbstractAutowireCapableBeanFactory抽象类里通过一个CopyOnWriteArrayList存放了所有的BeanPostProccessor注册Bean完成后执行

         由上,我感觉ScopeBeanFactory就是一个简化版的BeanFactory,接着跟着代码一探究竟。

2. 注册Bean

注册Bean, 通过name 和对象可以直接注册Bean。

    
    public void registerBean(Object bean) {
        this.registerBean(null, bean);
    }

    public void registerBean(String name, Object bean) {
        checkDestroyed();
        // avoid duplicated register same bean
        if (containsBean(name, bean)) {
            return;
        }

        Class<?> beanClass = bean.getClass();
        if (name == null) {
            name = beanClass.getName() + "#" + getNextId(beanClass);
        }
        initializeBean(name, bean);

        registeredBeanInfos.add(new BeanInfo(name, bean));
    }


        this.getOrRegisterBean, 如果没有Bean,那么根据class创建Bean

    public <T> T getOrRegisterBean(String name, Class<T> type) {
        T bean = getBean(name, type);
        if (bean == null) {
            // lock by type
            synchronized (type) {
                bean = getBean(name, type);
                if (bean == null) {
                    bean = createAndRegisterBean(name, type);
                }
            }
        }
        return bean;
    }

         也通过supplier传进来一个Bean, 执行apply 方法的时候回调。

    public <T> T getOrRegisterBean(Class<T> type, Function<? super Class<T>, ? extends T> mappingFunction) {
        return getOrRegisterBean(null, type, mappingFunction);
    }

    public <T> T getOrRegisterBean(String name, Class<T> type, Function<? super Class<T>, ? extends T> mappingFunction) {
        T bean = getBean(name, type);
        if (bean == null) {
            // lock by type
            synchronized (type) {
                bean = getBean(name, type);
                if (bean == null) {
                    // 执行目标方法,得到bean对象。
                    bean = mappingFunction.apply(type);
                    registerBean(name, bean);
                }
            }
        }
        return bean;
    }

3. 执行一系列的PostProccessor

         注册Bean后的初始化,执行类似于Spring 的Bean的初始化动作:

        执行一系列的PostProcessor, Spring里叫BeanPostProcessor, 这里只是换了个名字叫ExtensionPostProcessor。

    private void initializeBean(String name, Object bean) {
        checkDestroyed();
        try {
            if (bean instanceof ExtensionAccessorAware) {
                ((ExtensionAccessorAware) bean).setExtensionAccessor(extensionAccessor);
            }
            // 执行postProcessAfterInitialization(bean,name), 执行一系列的BeanPostProccessor
            for (ExtensionPostProcessor processor : extensionPostProcessors) {
                processor.postProcessAfterInitialization(bean, name);
            }
        } catch (Exception e) {
            throw new ScopeBeanException("register bean failed! name=" + name + ", type=" + bean.getClass().getName(), e);
        }
    }

        Spring 会在初始化完毕后,AbstractAutowireCapableBeanFactory实现了执行一系列的BeanPostProcessor

    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    AbstractAutowireCapableBeanFactory.this.invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, this.getAccessControlContext());
        } else {
            this.invokeAwareMethods(beanName, bean);
        }

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

        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
        }

        // 执行postProceesorAfterInitialization
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

        进入到 applyBeanPostProcessorsAfterInitialization方法: 


    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
        Iterator i$ = this.getBeanPostProcessors().iterator();

        do {
            if (!i$.hasNext()) {
                return result;
            }
            // 执行postProcessor
            BeanPostProcessor beanProcessor = (BeanPostProcessor)i$.next();
            result = beanProcessor.postProcessAfterInitialization(result, beanName);
        } while(result != null);

        return result;
    }

        看了代码后,我感觉Dubbo的ScopeBeanFactory的实现基本是借鉴于Spring 的BeanFactory的设计实现 ,更清晰明了啦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2417.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软考下午第5题——面向对象程序设计——代码填空(老程序员必得15分)

第五个题目分为C 和 Java两个题目&#xff0c;除去编写代码不同&#xff0c;考察的内容是完全相同的&#xff0c;选一个就行。建议Java&#xff0c;因为老程序员最近用的Java肯定对。 题目考察形式为给出类图描述和几乎全部代码&#xff0c;考生关键代码填空即可。 某软件公司…

【数据结构】简单认识:堆

数据结构&#xff1a;堆堆1.堆是什么&#xff1f;2.堆的特性。3.堆的操作原理①堆的插入原理②堆的删除原理堆 1.堆是什么&#xff1f; 堆是特殊的队列&#xff0c;不同于普通队列&#xff0c;从堆中取出元素是依照元素的优先级大小&#xff0c;而不是元素进入队列的先后顺序…

计算机毕业设计(附源码)python疫情防控管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

阿里/华为云服务器centos7.5 java部署环境快速搭建一条龙【git、maven、jdk8、docker安装nginx、mysql、redis】

文章目录linux常用命令汇总视频教程云服务器搭建java部署环境1.安装配置git2.安装jdk和maven下载安装3.安装docker4.安装docker-compose5.编排nginx6.编排mysql7.编排redislinux常用命令汇总 linux常用命令汇总 视频教程 云服务器java环境搭建一条龙&#xff08;1&#xff0…

数据分析 | Pandas 200道练习题,每日10道题,学完必成大神(6)

文章目录前期准备1. 使用绝对路径读取本地Excel数据2. 查看数据前三行3. 查看每一列数据缺失值情况4. 提取日期列含有空值的行5. 输出每列缺失值具体行的情况6. 删除所有缺失值的行7. 绘制收盘价的折线图8. 同时绘制开盘价与收盘价9. 绘制涨跌的直方图10. 让直方图给更细致本章…

MPEG vs JPEG

MPEG 是什么呢&#xff1f;看着很熟悉&#xff0c;于是想起了 FFmpeg。 于是不禁要问&#xff1a;二者有关系吗&#xff1f; FFmpeg 是一个完整的跨平台音视频解决方案&#xff0c;它可以用于处理音频和视频的转码、录制、流化处理等操作。其实是 FFmpeg 取名借鉴了 MPEG&…

UE4 回合游戏项目 02- 创建人物-敌人角色(动画蓝图练习)

在上一节&#xff08;UE4 回合游戏项目 01- 创建人物-玩家角色&#xff09;基础上创建敌人角色的动画蓝图 步骤&#xff1a; 1.创建动画蓝图 选择怪物骨骼 命名为enemy1_AnimBP 2.双击打开enemy1_AnimBP&#xff0c;创建一个新的状态机节点&#xff0c;连接到输出姿势 3.双击…

计算机毕业设计(51)java小程序毕设作品之教室图书馆座位预约小程序系统

项目背景和意义 目的&#xff1a;本课题主要目标是设计并能够实现一个基于微信小程序预约订座小程序&#xff0c;前台用户使用小程序&#xff0c;后台管理使用JavaMysql开发&#xff0c;后台使用了springboot框架&#xff1b;通过后台添加座位类型、座位号&#xff0c;用户通过…

JVM 的发展历程及其基本概念 (一)

一、JVM的基本介绍 1、随着Java7的正式发布&#xff0c;Java 虛拟机的设计者们通过JSR-292规范基本实现在Java虚拟机平台上运行非Java语言编写的程序。 Java虚拟机根本不关心运行在其内部的程序到底是使用何种编程语言编写的&#xff0c;它只关心“字节码”文件。也就是说Ja…

java线程简介

文章目录前言Java线程简介多线程的优点线程的优先级线程的状态daemon线程总结前言 很多地方我们都会用到线程&#xff0c;java操作系统的线程本质其实就是&#xff0c;你写了一个线程类&#xff0c;java替你一对一的在操作系统层面创建了一个线程。之前应该是这样的&#xff0…

【HTML】标签下合集~~~

&#x1f60a;博主页面&#xff1a;鱿年年 &#x1f449;博主推荐专栏&#xff1a;《WEB前端》&#x1f448; ​&#x1f493;博主格言&#xff1a;追风赶月莫停留&#xff0c;平芜尽处是春山❤️ 目录 一、图像标签和路径&#xff08;重点&#xff09; 1.图像标签 2.路径…

直播间数字化新趋势:打造内容良性循环

一年一度的「双十一」又来了&#xff0c;还记得去年的「双十一」热点吗&#xff1f; 去年「双十一」&#xff0c;李佳琦当天直播超过 12 小时&#xff0c;观看人数达到 2.49 亿人&#xff0c;再加上另一个顶流薇娅&#xff0c;二人当天总销售额高达 189 亿元。 这个数字&#x…

排序算法-冒泡排序(工具类)

冒泡排序 什么是冒泡排序 冒泡排序&#xff08;Bubble Sort&#xff09;&#xff0c;是计算机科学领域简单的排序算法 重复的访问每一个元素&#xff0c;依次相邻的两个元素进行比较大小&#xff0c;进行交换位置&#xff0c; 为什么叫冒泡排序&#xff1a; 越小的元素会经…

C - Bricks and Bags,E - Hanging Hearts,H-Leonard的子序列_树状数组优化dp,B - Hash 河南省赛

14天阅读挑战赛 C - Bricks and Bags 情况考虑少了&#xff0c;以为把最大值和最小值单独放在两个包里是最优的&#xff0c;其实不是&#xff0c;应该是分别枚举i&#xff0c;分别和最大值或最小值单独放在两个包里&#xff0c;然后去更新答案 #include<bits/stdc.h> …

基于stm32 ESP8266WiFi模块的基本通信

文章目录前言一、什么是ESP8266&#xff1f;二、ESP8266常用指令集三、模块的配置 及 指令的使用四、程序设计前言 本篇涉及到的模块与工具为&#xff1a; 1. ATK-ESP8266wifi模块 2. USB-UART模块 3. 串口调试助手 提取链接&#xff1a;https://pan.baidu.com/s/17xRlpnjp8j-…

软考下午题第2题——E-R图 UML图 逻辑结构设计-示题与解析

下午的第二题主要是找【属性】【主键】【外键】【候选键】之间的关系。 候选键&#xff1a;属性或者是属性组合&#xff0c;其值能够唯一地标识一个元组 主键&#xff1a;在一个关系中可能有多个候选键&#xff0c;从中选择一个作为主键 外键&#xff1a;如果一个关系中的属性或…

【JavaWeb】会话跟踪技术Cookie与Session原始真解

文章目录1 什么是会话&#xff1f;2 Cookie技术2.1 Cookie简介2.2 Cookie的理解与创建2.3 服务器获取Cookie与Cookie的修改2.4 Cookie的生命控制与生命周期2.5 Cookie有效路径Path设置3 Session会话技术3.1 初探Session3.2 Session的创建、获取与基本使用3.3 Session的生命控制…

使用Python的smtplib模块发送带附件的邮件

上一篇文章《使用Python的smtplib模块发送简单邮件》介绍了调用smtplib模块发送包含简单内容的邮件&#xff0c;本文继续学习参考文献1中的发送带附件的邮件的示例代码&#xff0c;同时由于参考文献1中的带附件邮件中并没有邮件附件&#xff0c;而仅仅是邮件内容中关联的内嵌资…

哪款半入耳式蓝牙耳机音质好?音质比较好的半入耳式蓝牙耳机推荐

半入耳式的蓝牙耳机相比入耳式的要舒适许多&#xff0c;佩戴更加的舒适透气&#xff0c;近年来&#xff0c;市面上的蓝牙耳机鱼龙混杂&#xff0c;人们选购蓝牙耳机对音质有一定的要求&#xff0c;下面是我整理的四款音质高的半入耳式蓝牙耳机&#xff0c;可以参考参考。 一、…

[carla入门教程]-1 安装carla环境

本专栏教程将记录我从安装carla到调用carla的pythonAPI进行车辆操控的全流程,带领大家从安装carla开始,到最终能够熟练使用carla仿真环境进行传感器数据采集和车辆控制. 第一节 carla 仿真环境的安装 准备工作: 在本节教程之前,需要大家安装ubuntu18.04以上的系统,并且安装对…