精华内容
下载资源
问答
  • 亲自动手写一个深度学习框架

    千人学习 2018-10-30 15:24:47
    本课程带领大家亲自动手写一个更方便大家使用的深度学习框架,帮助大家理解常用技术的底层实现。具体安排如下: 1.板书完成数学推导,同时画图讲解; 2.基础:Python实现多层感知器; 3.进阶:C++实现深度学习框架...
  • 自己动手RPC框架

    千次阅读 2019-01-13 02:08:02
    现在,自我挑战一下,动手写一个RPC框架。 高能预警:本文涉及到的知识点如下 Spring Boot2:起步依赖、自动配置,让应用开发变得简单 Spring的Java Bean配置,条件注解:灵活控制注入 基于JDK接口的动态代理...

    在上一篇博客中,介绍了RPC的主要概念和实现原理,然后基于TCP协议实现了一个非常简单的RPC小案例(点此回顾)。

    现在,自我挑战一下,动手写一个RPC框架。

    高能预警:本文涉及到的知识点如下

    • Spring Boot2:起步依赖、自动配置,让应用开发变得简单
    • Spring的Java Bean配置,条件注解:灵活控制注入
    • 基于JDK接口的动态代理了解一下?):发起远程调用对服务消费者来说是透明的
    • ZooKeeper了解一下?):提供树形目录结构,节点变化函数回调
    • Netty了解一下?):高性能的网络通信
    • 自定义注解:哪些类的实例提供远程服务,又是实例的哪些属性需要注入远程服务
    • Java内置的序列化了解一下?):网络中数据以二进制的形式进行传输

    先看下效果

    1、配置文件:开启服务注册、ZK地址和连接超时时间、暴露服务端口。

    2、服务提供者:用RpcService注解说明该bean提供远程调用服务。

    3、服务消费者:RpcReference注解为此属性注入远程调用服务的代理对象。

     

    4、注册中心:服务提供者启动后,在ZK成功创建了相关节点。

    5、调用服务:成功发起了一次远程过程调用。

    嘀,开车啦!

    嗤,源码下载地址:https://download.csdn.net/download/qq_31142553/10913525

    一、原理&流程

    敲黑板讲重点!!!

    Dubbo一样,分为服务提供者、服务消费者、注册中心三个主要角色。后面将逐一进行讲解。

    镇楼图

    RPC架构流程图

     

    二、代码结构

    我们将项目分为两个模块,一个核心模块,一个测试模块。大概代码结构如下

     

    主要maven依赖

            <!-- lombok,简化实体类结构 -->
            <dependency>
    			<groupId>org.projectlombok</groupId>
    			<artifactId>lombok</artifactId>
    			<!-- <optional>true</optional> -->
    		</dependency>
    
            <!-- netty,高性能服务通信 -->
    		<dependency>
    			<groupId>io.netty</groupId>
    			<artifactId>netty-all</artifactId>
    		</dependency>
    
    		<!-- zk,注册中心 -->
    		<dependency>
    			<groupId>org.apache.zookeeper</groupId>
    			<artifactId>zookeeper</artifactId>
    			<version>3.4.12</version>
    		</dependency>

    三、角色详解

    因为基于Java Bean的配置比较灵活,所以我们建立一个全局配置类,在这里配置需要交给Spring IOC容器管理的对象。但是,如果系统不打算使用RPC服务,那就没必要加载这个配置类了。因此,我们自定义一个注解,如果在Spring Boot启动类上使用了此注解,那么此全局配置类才生效。

    1、服务提供者

    概述

    服务提供者系统启动时,如果启用了服务注册功能,就将提供服务的bean信息注册到ZooKeeper,并在内存维护一个interfaceName-bean的映射关系集合,最后在指定端口开启一个监听远程调用请求的服务。

    详解

    是否启用服务注册功能,可以从配置属性读取。采用条件注解的方式,如果启用了,就注册一个专门用于维护与ZooKeeper的连接会话的实例到IOC容器,在构造函数里面初始化它的ZK实例,并判断是否需要创建ZK的服务根节点。然后,还要注册一个RPC服务到IOC容器,这个服务在Spring容器加载完成之后,获取所有带了自定义的、表示提供远程服务的注解的bean,先将它们存到本地内存维护的一个Map集合里面,以接口全类名为key,bean实例为value,这样,远程过程调用的请求过来之后,就从这个map里面根据接口名找到对应的bean来处理了。然后,还要将这些bean实例信息放到ZK上面,以提供服务消费方去查询获取。至于存什么信息呢?首先是需要这些bean的接口全类名,然后是本机启动的监听请求服务的IP和端口。所以,在ZK服务根节点下,创建一个以接口全类名为名称的永久节点,然后创建一个临时序列子节点,以本机IP和监听端口、当前时间戳(处理一台服务器的一个接口有多个实现类的问题)命名。最后,还要启动一个Netty服务端,绑定本机的IP和端口,端口可以写到配置里面、与前文说的保持一致,添加业务处理的Handler,业务处理主要是根据请求的接口名、方法名、参数列表找到本地内存维护的map里面的服务实例,通过反射调用并返回执行结果。

    2、服务消费者

    概述

    服务启动时,从注册中心订阅(先查,后续变化自动触发更新)自己需要的服务到本地列表。方法调用时,利用代理先去本地列表查询到服务提供所在IP和端口,然后发起Netty请求,将响应作为远程调用的执行结果返回。

    详解

    首先,服务消费者系统启动时,先注册一个与ZooKeeper的连接会话的实例到IOC容器。然后,查询所有bean中带了自定义的、表示需要远程服务的注解的属性,根据它们的类型名称到ZK上面查询同名节点,存在的话获取它的所有孩子节点名称,然后保存到一个自己定义的、类似Map<String, Set<String>>结构的集合里,同时还要为类名的节点注册子节点变化监听器,触发时重新读取其子节点更新到集合里。接着,利用反射为属性赋值一个代理对象,这个代理对象在方法被调用时,将方法调用信息封装成请求参数,根据自己的类型名称到集合里面找到符合的服务提供者所在的IP和端口后发起请求,并将响应结果返回。

    四、代码说明

    由于代码量有点大,我也不知道怎么贴。就将这些类是做什么用的简单说明一下,比较关键的部分附上截图。

    推荐感兴趣的小伙伴直接去下载源码:https://download.csdn.net/download/qq_31142553/10913525

    (1)annotation包

    EnableRpcConfiguration:自定义注解,用于Spring Boot启动类上面。有此注解时,配置类RpcConfiguration才生效,系统才使用RPC功能。

    RpcReference:自定义注解,用于Spring Bean的属性上,表明此字段需要注入远程调用的代理对象。

    RpcService:自定义注解,用于Spring Bean的类上面,表明该实例提供远程调用服务。需要设置interfaces属性,指明提供哪些接口的服务。

    (2)client包

    NodeChildrenChangedWatcher:子节点变化观察者,用于服务消费者监听ZooKeeper指定节点的变化从而更新服务信息列表。

    RpcClientHandler:用于服务消费者向服务提供者发送请求并接收响应。

    RpcInjectHandler:客户端核心类,从ZooKeeper获取需要的服务信息,为带RpcReference注解的属性设置远程调用的代理对象。

     

     

    (3) common包

    RpcDecoder:Netty解码器,将字节数组转为Java对象。

    RpcEncoder:Netty编码器,将Java对象转为字节数组。

    RpcRequest:RPC请求封装类,有接口名称、方法名称、参数列表(类型和值)。

    RpcResponse:RPC结果封装类,有响应结果、异常。

    (4)conf包

    Consts:常量,有zk服务根节点 、本机IP。

     RpcConfiguration:RPC配置类,配置所有注入IOC容器的bean。

    (4)server包

    RpcServer:将提供RPC服务的bean存到本地服务列表,并注册到ZooKeeper

    RpcServerHandler:处理服务消费者的请求,反射调用本地方法,并将执行结果返回。

    ServerListener:开启Netty服务端监听。

    (5)util包

    HashMultimap:类似Google Guava的同名类,提供Map<K, Set<V>>结构的集合。

    IpUtils:获取本机IP地址。

    RpcException:RPC异常类。

    SerializationUtils:Java内置的序列化和反序列化功能。

    (6)zk包

    ZkClient:维护服务消费者与ZooKeeper的连接会话。

    ZkServer:维护服务提供者与ZooKeeper的连接会话,并创建服务根节点(需要的话)。

    后续可以考虑加入负载均衡、服务容错等功能! 

    源码下载地址:https://download.csdn.net/download/qq_31142553/10913525

    展开全文
  • 写一个自己的Web前端框架

    千次阅读 2018-03-21 14:16:05
    最近一直在看动脑学院的阿里前端p6架构师培训计划的直播,昨天场比较精彩。讲的是一套架构,其称之为“驱动框架”。今天做一下总结。 一些技巧 后端返回的JSON数据键名与本地模块名相同(便于获取) JSON...

    “首先新年快乐!”

    这里写图片描述

    前言

    最近一直在看动脑学院的阿里前端p6架构师培训计划的直播,昨天一场比较精彩。讲的是一套架构,其称之为“驱动框架”。今天做一下总结。

    一些技巧

    • 后端返回的JSON数据键名与本地模块名相同(便于获取)
    • JSON数据键名与HTML表单标签元素id相同(便于渲染)
      为什么这样呢?在调用的时候非常方便,直接处理,可以看看以下代码。

    框架

    var MetaDriver = (function (global,factory) {
        return factory.call(this);
    })(this,function () {
        var _META_ = {
            init:function (data) {
                alert("init OK!");
                this.fetch(data)
                this.render()
            },
            fetch:function (data) {
                for (const m in _MODULE_) {
                    if (_MODULE_.hasOwnProperty(m)) {
                        const element = _MODULE_[m];
                        _MODULE_[m].data = data[m];
                    }
                }
            },
            render:function(){
                for(var m in _MODULE_){
                    _MODULE_[m].render()
                }
            }
        };
        var _MODULE_ = {
            module1:{
                data:null,
                view:"hello",
                before:function () {
                    console.log("before")
                },
                render:function () {
                    if(this.before){
                        this.before();
                    }
                    alert(this.view);
                    if(this.after){
                        this.after();
                    }
                },
                after:function () {
                    console.log("after")
                }
            }
        }
        return _META_;
    })

    个人理解

    • 让自己的模块存在于一个闭包里,避免变量名冲突覆盖。jquery源码便有此种方式。
      javascript
      let MyModuleDriver = (function(global,factory){
      return factory.call(global);
      })(this,function(){
      let _META_ = {
      init:function(){}
      }
      return _META;
      })
    • 分治与统一管理

    所谓的分治就是页面的不同模块区分管理,就是以上代码的MODULE部分。
    每一个页面模块分一个module,每一个module都有自己管理的内容。包括数据(data)、视图(view)、渲染器(render)等等。这有点类似于现在主流的框架,比如Vuejs。
    所谓的统一管理是指驱动全部模块,就是以上代码META部分。有个初始化方法(init),用于加载一些一次性的功能,然后有数据加载函数(fetch)用于将某些模块的数据进行赋值,也有整体渲染器,用于渲染所有模块。

    更加神奇的一点

    这一点直接听得我两眼放光,真所谓返璞归真、大道归一。
    在防止数据重复加载方面炒鸡有意思。比如用相同的表单请求的是相同的数据,他要重新渲染视图。此时可以给模块加一个渲染锁。

    var _MODULE_ = {
            module1:{
                data:{},
                view:"hello",
                lock:false,
                before:function () {
                    console.log("before")
                },
                render:function () {
                    if(this.before){
                        this.before();
                    }
                    if(this.lock){
                        alert(this.view);
                        this.lock = false;
                    }
                    if(this.after){
                        this.after();
                    }
                },
                after:function () {
                    console.log("after")
                }
            }
        }
        //有新数据来的时候_META_开锁
        _META_={
            fetch:function (data) {
                for (const m in _MODULE_) {
                    if (_MODULE_.hasOwnProperty(m)) {
                        const element = _MODULE_[m];
                        _MODULE_[m].data = data[m];
                        // 开锁!
                        _MODULE_[m].lock = true;
                    }
                }
            }
        }
    

    这里的lock起了关键的作用,这一点类似于同步锁,一样的道理。当有新数据来的时候才加载,没有新数据的时候锁一直是关着的,直接越过加载。

    调用

    • 在相应的HTML中引用此JS
    • 直接调用MyMetaDriver(闭包返回的META)中的方法即可,类似调用即可。
    展开全文
  • 自己手写一个Mybatis框架(简化)

    千次阅读 2018-03-23 10:36:45
    MyBatis框架的核心功能其实不难,无非就是动态...、Mybatis框架流程简介在手写自己的Mybatis框架之前,我们先来了解一下Mybatis,它的源码中使用了大量的设计模式,阅读源码并观察设计模式在其中的应用,才能够...

    MyBatis框架的核心功能其实不难,无非就是动态代理和jdbc的操作,难的是写出来可扩展,高内聚,低耦合的规范的代码。本文完成的Mybatis功能比较简单,代码还有许多需要改进的地方,大家可以结合Mybatis源码去动手完善。

    一、Mybatis框架流程简介

    在手写自己的Mybatis框架之前,我们先来了解一下Mybatis,它的源码中使用了大量的设计模式,阅读源码并观察设计模式在其中的应用,才能够更深入的理解源码(ref:Mybatis源码解读-设计模式总结)。我们对上图进行分析总结:

    mybatis的配置文件有2类mybatisconfig.xml,配置文件的名称不是固定的,配置了全局的参数的配置,全局只能有一个配置文件。Mapper.xml 配置多个statemement,也就是多个sql,整个mybatis框架中可以有多个Mappe.xml配置文件。通过mybatis配置文件得到SqlSessionFactory通过SqlSessionFactory得到SqlSession,用SqlSession就可以操作数据了。SqlSession通过底层的Executor(执行器),执行器有2类实现:

    基本实现带有缓存功能的实现MappedStatement是通过Mapper.xml中定义statement生成的对象。参数输入执行并输出结果集,无需手动判断参数类型和参数下标位置,且自动将结果集映射为Java对象HashMap,KV格式的数据类型Java的基本数据类型POJO,java的对象二、梳理自己的Mybatis的设计思路

    根据上文Mybatis流程,我简化了下,分为以下步骤:

    1.读取xml文件,建立连接

    从图中可以看出,MyConfiguration负责与人交互。待读取xml后,将属性和连接数据库的操作封装在MyConfiguration对象中供后面的组件调用。本文将使用dom4j来读取xml文件,它具有性能优异和非常方便使用的特点。

    2.创建SqlSession,搭建Configuration和Executor之间的桥梁

    我们经常在使用框架时看到Session,Session到底是什么呢?一个Session仅拥有一个对应的数据库连接。类似于一个前段请求Request,它可以直接调用exec(SQL)来执行SQL语句。从流程图中的箭头可以看出,MySqlSession的成员变量中必须得有MyExecutor和MyConfiguration去集中做调配,箭头就像是一种关联关系。我们自己的MySqlSession将有一个getMapper方法,然后使用动态代理生成对象后,就可以做数据库的操作了。

    3.创建Executor,封装JDBC操作数据库

    Executor是一个执行器,负责SQL语句的生成和查询缓存(缓存还没完成)的维护,也就是jdbc的代码将在这里完成,不过本文只实现了单表,有兴趣的同学可以尝试完成多表。

    4.创建MapperProxy,使用动态代理生成Mapper对象

    我们只是希望对指定的接口生成一个对象,使得执行它的时候能运行一句sql罢了,而接口无法直接调用方法,所以这里使用动态代理生成对象,在执行时还是回到MySqlSession中调用查询,最终由MyExecutor做JDBC查询。这样设计是为了单一职责,可扩展性更强。

    三、实现自己的Mybatis

    工程文件及目录:

    首先,新建一个maven项目,在pom.xml中导入以下依赖:

    创建我们的数据库xml配置文件:

    然后在数据库创建test库,执行如下SQL语句:

    创建User实体类,和UserMapper接口和对应的xml文件:

    基本操作配置完成,接下来我们开始实现MyConfiguration:

    用面向对象的思想设计读取xml配置后:

    Function对象包括sql的类型、方法名、sql语句、返回类型和参数类型。

    接下来实现我们的MySqlSession,首先的成员变量里得有Excutor和MyConfiguration,代码的精髓就在getMapper的方法里。

    紧接着创建Excutor和实现类:

    MyExcutor中封装了JDBC的操作:

    MyMapperProxy代理类完成xml方法和真实方法对应,执行查询:

    到这里,就完成了自己的Mybatis框架,我们测试一下:

    执行结果:

    查询一个不存在的用户试试:

    到这里我们就大功告成了!

    我是个普通的程序猿,水平有限,文章难免有错误,欢迎牺牲自己宝贵时间的读者,就本文内容直抒己见,我的目的仅仅是希望对读者有所帮助。源码地址:https://github.com//liugh-mybatis

    原文地址:http://baijiahao.baidu.com/s?id=1595688310049388329&wfr=spider&for=pc


    展开全文
  • 手写一个简单的Spring框架

    千次阅读 2018-09-12 22:57:40
    手写Spring 初始化流程 Markdown和扩展Markdown简洁的语法...离线博客 导入导出Markdown文件 丰富的快捷键 快捷键 加粗 Ctrl + B 斜体 Ctrl + I 引用 Ctrl + Q 插入链接 Ctrl + L 插入代码 Ctrl + K 插...

    手写Spring

    1、目录

    2、说明

    此项目主要实现了spring的IOC和AOP功能。采用注解的方式实现,xml的方式没有实现。

    3、初始化流程

    这里写图片描述

    初始化流程共有五个:读取注解,对象实例化,aop代理对象生成,url与方法关联,变量注入。

    4、扫描文件

    这里写图片描述

    5、对象实例化

    这里写图片描述

    6、aop代理对象生成

    代理对象的优先级:先生成方法级别的代理,再生成类级别的代理。
    执行起来表现为:先执行类级别的代理,再执行方法级别的代理。
    这里写图片描述

    7、url与方法关联

    这里写图片描述

    8、变量注入

    这里写图片描述

    9、HttpServlet

    继承HttpServlet,然后在doGet、doPost方法中通过url获取到方法后,反射执行即可。一个简易的spring框架即完成。
    附上github源码:https://github.com/codeljy/myspring

    展开全文
  • 大概 2 个月前,我说过要利用业余时间写一个简单的 RPC 框架,今天(2020-06-05)总算将其开源出来,希望对小伙伴们有帮助。 虽说 RPC 的原理实际不难,但是,自己在实现的过程中自己也遇到了很多问题。Guide-rpc-...
  • 自己动手模仿 springmvc 写一个 mvc框架

    千次阅读 热门讨论 2017-05-27 10:23:09
    我觉得,完整的自己动手去实现一个,是最好的方式。 bfmvc模仿springmvc的轻量级web框架,适合学习和搭建小型web项目使用,持续更新项目地址:https://github.com/CFshuming/bfmvc感兴趣的记得star哟~目录介绍
  • 从零开始写一个框架的详细步骤

    万次阅读 多人点赞 2016-05-31 17:28:27
    如果你打算写框架,那么肯定心里已经有一个初步的定位,比如它是一个缓存框架、Web MVC框架、IOC框架、ORM/数据访问框架、RPC框架或是一个用于Web开发的全栈式框架。 是 否要重复造轮子?除非是练
  • 写一个框架的详细步骤

    万次阅读 多人点赞 2016-05-31 10:44:15
    如果你打算写框架,那么肯定心里已经有一个初步的定位,比如它是一个缓存框架、Web MVC框架、IOC框架、ORM/数据访问框架、RPC框架或是一个用于Web开发的全栈式框架。 是 否要重复造轮子?除非是练手项
  • 从零开始写一个RPC框架的详细步骤

    千次阅读 2017-01-09 00:20:58
    ...所谓定位就是回答几个问题,我出于什么目的要写一个框架,我的这个框架是干什么的,有什么特性适用于什么场景,我的这个框架的...如果你打算写框架,那么肯定心里已经有一个初步的定位,比如它是一个缓存框架
  • 手写Spring框架

    万次阅读 多人点赞 2019-01-25 15:30:05
    在学习完Spring框架之后, 我们知道了 Spring容器, IOC, AOP, 事务管理, SpringMVC 这些Spring的核心内容, 也知道了它们底层实现的基本原理, 比如Spring容器就是Map映射, IOC底层就是反射机制, AOP底层是动态代理, ...
  • 最近这段时间在研究怎么写一个web框架自己也动手了个雏形,在这个过程中受益良多。个文章记录下思路。另外,强烈推荐《架构探险:从零开始Java Web框架》这本书,虽然我现在只看了第三章和第四章的一点点,...
  • Spring可以理解为一个工厂,负责对象的创建和对象间关系的维护。IoC即控制反转,简单点说就是原来的对象是在要使用之前通过在代码里通过new 的方式创建出来的而IOC的思想则是由spring容器创建同一创建(配置文件中...
  • Java框架总结

    万次阅读 多人点赞 2020-01-17 14:14:13
    本系列用来记录常用java框架的基本概念、区别及联系,也记录了在使用过程中,遇到的一些问题的解决方法,方便自己查看,也方便大家查阅。 欲速则不达,欲达则欲速! 、SSH 1、基本概念 SSH框架是JAVA EE中三种...
  • 在我早期的篇博文Java反射机制的原理和用途中,文末我到过:"如果你不做框架的话,基本上是用不到反射机制的,我们大多时候是使用框架的一方,而反射机制都已经在底层实现过了,因此,我们不必担心,我们会...
  • 从0开始前端UI框架:概述

    千次阅读 2020-04-19 16:54:30
    缘起 经常听说:不要重复造轮子,我深同此...但是,闲暇之余,如果你精力充足,又喜欢窥探轮子的秘密,那么仿造现成轮子造出一个产品也是一件酷毙了的事情。 博主在开发需求过程中,就深刻体会到现成UI框架没法满足...
  • 自己实现一个Spring 框架

    千次阅读 2018-09-07 20:48:59
    我们在模拟一个Spring 框架时,肯定要先清楚Spring 的原理。大家普遍熟悉的就是IOC 和 AOP。IOC 控制反转,就是Spring 在托管整个bean ,AOP 面向切面的编程,就是一个动态代理,在方法执行时,动态的生成一些...
  • 最近学习了一下spring的相关内容,所以也就想要照猫画虎地记录和实现一下spring的框架,mini-spring尽量实现spring的核心功能。 、项目结构 本项目使用gradle进行构建,其中mini-spring为根模块,包含两子模块:...
  • 自己动手编写一个框架, 帮助学习思考目前常用框架的架构. 更加熟悉PHP脚本语言, 学习理解设计思想, 设计原则, 设计模式. 2.学习/操作 TBD 后续补充 ... 3.问题/补充 ...
  • 如果你想写自己的Benchmark框架

    万次阅读 2020-07-11 11:03:13
    使用过JMH的同学一定会惊叹它的神奇。JMH作为一个优秀的...作为一个有极客精神的程序员,那么有没有想过去自己实现一个Benchmark框架呢? 在实现Benchmark框架的时候有需要注意些什么问题呢?快来一起看看吧。
  • 工作中我们或多或少都需要自己搭建一个框架,现在常见的Java开源框架组合方式主要为:SSH,spring+springMVC+JDBC,SSM。 其中SSM目前无论是培训机构培训亦或是招聘。都会将会使用SSM框架作为一个重要能力来作为...
  • 笔者之前沉迷游戏无法自拔,但是现在之前...从来没有系统的总结归纳过学过的知识,于是决定自己写个框架试试,也可以查漏补缺,不懂得地方就多看看别的怎么处理的。所以开贴记录下自己的学习成果,框架还不完善只是作为
  • 自己写框架源码

    千次下载 热门讨论 2013-08-19 17:28:54
    自己写框架. 基础类库。 数据库访问器类库。 数据访问层基础类库。 业务逻辑层基础类库。 UI基础类库。 MEF基础类库。 View Model基础类库。 代码生成器。 工厂类库.
  • 教你响应式框架

    万次阅读 2016-03-13 12:24:38
    在真正开始编写自己的响应式框架之前,我们先来从观察者模式...它定义了一种以对多的依赖关系,让多个观察者(订阅者)同时观察(监听)一个被观察者(主题),当被观察者的状态发生变化时,会通知所有的观察者对象。
  • 偶然接触了bootstrap,感觉不错。现在正学习用bootstrap做网站后台,自己特意下了一些素材,整理了一下,希望对大家有用。
  • 当我们的SQL语句需要传入参数时,我们的参数是怎么绑定到SQL语句中的?

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 885,341
精华内容 354,136
关键字:

如何自己写一个框架