谢杨易
《精通推荐算法》独著作者。在阿里、腾讯工作多年。优快云博客专家,原创文章100余篇。
展开
-
mybatis源码分析1 - 框架
1 源码结构我们分析的mybatis源码version为3.4.5,mybaits-spring源码version为2.0.0-SNAPSHOT。先看mybatis的源码目录结构,如下图所示。我们只用看src/main/java下的目录即可。annotations:注解定义,我们知道mybatis配置可以采用XML文件形式,也可以采用注解形式binding:主要是mapper动原创 2018-01-14 12:08:56 · 16236 阅读 · 3 评论 -
mybatis源码分析7 - mybatis-spring读写数据库全过程
1 引言mybatis-spring中,我们利用Spring容器注入的方式创建了sqlSessionFactory,从而完成了mybatis的初始化。那么如何来读写数据库呢?最简单的方式是,和mybatis中一样,利用sqlSessionFactory的openSession来创建sqlSession,然后利用它来select或update,或者mapper方式。这种方式每次都需要手动open原创 2018-01-13 22:00:26 · 15692 阅读 · 1 评论 -
mybatis源码分析6 - mybatis-spring容器初始化
1 引言使用 MyBatis-Spring 模块,我们可以在Spring中使用mybatis,让Spring容器来管理sqlSessionFactory单例的创建。如以下代码bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> property name="dataSourc原创 2018-01-13 20:23:36 · 16064 阅读 · 3 评论 -
mybatis源码分析5 - mapper读写数据库完全解析
1 引言和主要类上一节讲解了sqlSession读写数据库的整个流程和四大组件的执行过程,相信大家对mybatis操作数据库有了一定的了解。上一节还提到过,其实我们还可以通过mapper方式读写数据库,并且mybatis建议使用mapper方式,而不是直接通过sqlSession的selectList update等方法。使用mapper方式的例子如下// 读取XML配置文件String reso原创 2018-01-10 14:56:19 · 16701 阅读 · 3 评论 -
mybatis源码分析4 - sqlSession读写数据库完全解析
1 引言和主要类创建完sqlSession实例后,我们就可以进行数据库操作了。比如通过selectOne()方法查询数据库,如代码// 读取XML配置文件String resource = "main/resources/SqlMapConfig.xml";InputStream inputStream = Resources.getResourceAsStream(resourc原创 2018-01-09 18:55:46 · 16262 阅读 · 4 评论 -
mybatis源码分析3 - sqlSession的创建
1 引言和主要类初始化mybatis,也就是创建完单例SqlSessionFactory后,就进入到了mybatis的运行阶段。mybatis每次的运行都是通过SqlSession对象来进行,它是运行时的核心。不同于SqlSessionFactory,SqlSession不是线程安全的,故一般建议放在局部作用域中定义, 且使用完后close掉。我们使用mybatis创建SqlSession十分原创 2018-01-09 12:03:12 · 16377 阅读 · 2 评论 -
mybatis源码分析2 - SqlSessionFactory的创建
mybatis源码分析2 - SqlSessionFactory的创建1 主要类初始化mybatis的过程,其实就是创建SqlSessionFactory单例的过程。下面是一个简单的初始化例子。String resource = "main/resources/SqlMapConfig.xml";InputStream inputStream = Resources.getR原创 2018-01-07 16:29:00 · 16306 阅读 · 5 评论 -
Redux源码分析
1 redux使用步骤React仅仅是一个前端View框架库,可以看做是MVC里面的V。没有解决组件间通信,MVC分离,数据共享等问题。Redux的出现使得这些都不是问题。使用Redux也比较简单,步骤大概如下编写React Component,这里不涉及Redux编写reducer,它接收一个state和action,返回一个新的statecreateStore(reducer) 得到sto原创 2017-07-20 23:45:01 · 16531 阅读 · 1 评论 -
Spring源码分析4 — spring bean创建和初始化
1 介绍创建并初始化spring容器中,refresh()方法中解析xml配置文件,注册容器后处理器,bean后处理器,初始化MessageSource,ApplicationEventMulticaster广播器,注册完ApplicationListener监听器后,关键一步就是创建和初始化其他非lazy-init的singleton beans。这样在容器初始化好的时候,这些singleton原创 2017-07-14 17:23:08 · 17960 阅读 · 2 评论 -
Spring源码分析3 — spring XML配置文件的解析流程
1 介绍创建并初始化spring容器中,关键一步就是读取并解析spring XML配置文件。这个过程比较复杂,本文将详细分析整个流程。先看涉及到的关键类。XmlWebApplicationContext:web应用的默认Spring容器XmlBeanDefinitionReader:读取XML并解析xml文件DocumentLoader:文件先被读取为了原始的输入流InputStream,然后封装为原创 2017-07-13 21:08:57 · 17949 阅读 · 22 评论 -
Spring源码分析2 — 容器启动流程
1 主要类部署web应用时,web容器(比如Tomcat)会读取配置在web.xml中的监听器,从而启动spring容器。有了spring容器之后,我们才能使用spring的IOC AOP等特性。弄清spring容器启动流程,有利于理解spring IOC中的各种特性,比如BeanPostProcessor,MessageSource,ApplicationListener等。我们先来看下容器启动流原创 2017-07-13 15:17:15 · 13337 阅读 · 8 评论 -
React源码分析7 — React合成事件系统
1 React合成事件特点React自己实现了一套高效的事件注册,存储,分发和重用逻辑,在DOM事件体系基础上做了很大改进,减少了内存消耗,简化了事件逻辑,并最大化的解决了IE等浏览器的不兼容问题。与DOM事件体系相比,它有如下特点React组件上声明的事件最终绑定到了document这个DOM节点上,而不是React组件对应的DOM节点。故只有document这个节点上面才绑定了DOM原生事件,原创 2017-03-10 23:36:48 · 12630 阅读 · 4 评论 -
React源码分析6 -- 组件通信,refs,key,ReactDOM
1 组件间通信父组件向子组件通信React规定了明确的单向数据流,利用props将数据从父组件传递给子组件。故我们可以利用props,让父组件给子组件通信。故父组件向子组件通信还是很容易实现的。引申一点,父组件怎么向孙子组件通信呢?可以利用props进行层层传递,使用ES6的…运算符可以用很简洁的方式把props传递给孙子组件。这里我们就不举例了。要注意的一点是,setProps,replacePr原创 2017-03-07 09:06:46 · 16313 阅读 · 0 评论 -
React源码分析5 — setState机制
1 概述React作为一门前端框架,虽然只是focus在MVVM中的View部分,但还是实现了View和model的绑定。修改数据的同时,可以实现View的刷新。这大大简化了我们的逻辑,只用关心数据流的变化,同时减少了代码量,使得后期维护也更加方便。这个特性则要归功于setState()方法。React中利用队列机制来管理state,避免了很多重复的View刷新。下面我们来从源码角度探寻下setSt原创 2017-03-02 11:57:31 · 22226 阅读 · 4 评论 -
React源码分析4 — React生命周期详解
1 React生命周期流程调用流程可以参看上图。分为实例化,存在期和销毁三个不同阶段。介绍生命周期流程的文章很多,相信大部分同学也有所了解,我们就不详细分析了。很多同学肯定有疑问,这些方法在React内部是在哪些方法中被调用的呢,他们触发的时机又是什么时候呢。下面我们来详细分析。2 实例化生命周期getDefaultProps在React.creatClass()初始化组件类时,会调用getDefa原创 2017-02-27 14:19:04 · 20001 阅读 · 1 评论 -
React源码分析3 — React组件插入DOM流程
React组件插入流程1 简介React广受好评的一个重要原因就是组件化开发,一方面分模块的方式便于协同开发,降低耦合,后期维护也轻松;另一方面使得一次开发,多处复用称为现实,甚至可以直接复用开源React组件。开发完一个组件后,我们需要插入DOM中,一般使用如下代码ReactDOM.render( <h1>Hello, world!</h1>, document.getElementByI原创 2017-02-23 18:08:37 · 20784 阅读 · 4 评论 -
React源码分析2 — 组件和对象的创建(createClass,createElement)
1 组件的创建React受大家欢迎的一个重要原因就是可以自定义组件。这样的一方面可以复用开发好的组件,实现一处开发,处处调用,另外也能使用别人开发好的组件,提高封装性。另一方面使得代码结构很清晰,组件间耦合减少,方便维护。ES5创建组件时,调用React.createClass()即可. ES6中使用class myComponent extends React.Component, 其实内部还是调原创 2017-02-18 18:44:41 · 11216 阅读 · 5 评论 -
React源码分析1 -- 框架
1 源码结构我们分析的React源码version为16.0.0-alpha.3,源码目录如下图所示。含义如下 addons:插件,一些比较有用的工具,如transition动画 isomorphic: 同构,服务端在页面初次加载时,将所有方法渲染好,一次性交给客户端。这样可以减少Ajax shared: 共用方法,一些utils test: 测试方法 renderers: React代码核心,大部...原创 2017-02-18 18:42:01 · 21814 阅读 · 3 评论 -
浏览器内核分析7 -- JavaScript引擎
1 JS语言与性能问题JS比Java慢的原因和大多数解释型语言一样,JavaScript运行也比较慢,和Java等静态编译语言相比,究其原因大概有JS变量无类型信息,不能做偏移信息查找,偏移信息共享等编译阶段的优化JS将源码编译为字节码的过程要占用运行时间,而Java的编译则是开发阶段,不占用任何运行时间。故Java可以尽可能的在编译阶段做优化JS引擎组成一个JS引擎大概包含以下几个部分。编原创 2017-02-16 21:29:08 · 15823 阅读 · 0 评论 -
浏览器内核分析6 -- 布局和绘制
DOM树构建完成后,就开始构建RenderObject树了。渲染过程分为布局和绘制两个阶段,最终得到用户可见区域(ViewPort)图像在内存中的表示Bitmap。1 RenderObjectRenderObject是渲染树中的子节点,也是RenderText,RenderImage等很多渲染树节点的基类,所以比较关键。主要方法递归遍历等操作,如parent(), firstChild(), ne原创 2017-02-16 20:56:11 · 925 阅读 · 0 评论 -
浏览器内核分析5 -- CSS解释器和样式布局
1 主要类CSSStyleSheet:描述CSS文件,不论是内嵌的,还是引用的外部文件CSSRule:一条CSS规则,解析如下的CSS代码得到:p, div { margin-top: 3px; color: #ffffff;}包含选择器和属性表两部分CSSSelector:选择器属性集合:一个CSSPropertyID: CSSValue组成的map,描述了元素的属性。2 解释过程解释原创 2017-02-16 19:34:42 · 968 阅读 · 0 评论 -
浏览器内核分析4 -- HTML解释器和DOM模型
1 概述Browser进程完成HTML CSS等资源文件的加载后,Renderer进程就需要开始渲染流程了。下面这张图描述了整个渲染流程。主要过程分为以下几步:读取HTML文件,解析并生成DOM树读取CSS文件,解析生成样式规则表,并根据选择器找到元素的匹配规则由DOM树和匹配规则生成RenderObject树,并进行布局和绘制执行JavaScript时,可能会改变DOM结构和CSS样式,此原创 2017-02-16 17:17:32 · 2345 阅读 · 0 评论 -
浏览器内核分析3 -- 资源加载和网络栈
1 网络资源资源加载器网页加载中需要获取的资源文件很多,有HTML,JavaScript,CSS,图片,SVG,CSS Shader,视频音频字幕,字体文件,XSL样式表等。不同资源有不同的加载器,主要分为三类:特定资源加载器:处理特定资源请求,如ImageLoader FontLoader缓存资源加载器:从内存中获取资源,CachedResourceLoader通用资源加载器:从网络或硬盘中原创 2017-02-15 22:57:08 · 1118 阅读 · 0 评论 -
浏览器内核分析2 -- Webkit和Chromium源码结构
1 Webkit架构Webkit和Blink代码量都是几百万行级别,阅读难度很大,故先了解下它的大体架构是十分有意义的。下面是《Webkit技术内幕》一书中给出的架构图由图中可见,大体分为以下几个层次 1. 操作系统:WebKit可以在不同OS上运行,如mac OS,Windows,Linux等。 2. 三方库:WebKit依赖了很多三方库,如音频,视频等 3. WebKit:大概分为两个部分原创 2017-02-15 16:33:50 · 14991 阅读 · 0 评论 -
浏览器内核分析1 -- 概述
1 主流浏览器市场份额根据Net Applications公司分析,2016年12月全球浏览器市场份额如下图其中Chrome已经占据56%市场,而IE下滑到20%。开源浏览器Chrome Safari Firefox之和达到72%之多。在开源越来越流行的当下,开源浏览器也是越来越受欢迎。2 主流浏览器内核分析现今五大主流浏览器IE、Firefox、Safari、Chrome及Opera的内核分别如下原创 2017-02-15 14:01:17 · 1643 阅读 · 0 评论 -
Http协议简介
1)URI和URLURI:统一资源标识符。用于标识某一互联网资源名称的字符串。包括URL和URNURL:统一资源定位符。URI的一种形式。现在基本都是用URL来代表URI。可以将URL和URI等同来看待。URN:统一资源名称。URI的另一种形式。仅仅处于试验阶段。它用资源名称来代表资源,与路径无关。故资源移动位置时,不用改变。原创 2016-09-04 12:01:12 · 2122 阅读 · 2 评论 -
OKHttp源码分析3 - HttpEngine底层实现
上篇文章,我们详细分析了OKHttp中Request的创建和发送过程。其中sendRequest(), readResponse(), followUpRequest()三个关键方法在底层HttpEngine中实现。革命尚未成功,我们接下来在这篇文章中分析HttpEngine中的这三个方法。原创 2016-09-04 11:51:26 · 5349 阅读 · 17 评论 -
OKHttp源码分析2 - Request的创建和发送
OKHttp使用起来还是相当简单的,大家是否已经跃跃欲试想了解下它的底层实现呢。从使用中我们看到,它大致分为两步:Request的创建和Request的发送。现在就带大家一起来分析下这两个步骤。对Http协议不熟悉的同学,可以先看看我的这篇文章[Http协议简介](http://blog.youkuaiyun.com/u013510838/article/details/52431558)原创 2016-09-03 18:19:05 · 2307 阅读 · 7 评论 -
OKHttp源码分析1 - 框架
1 OKHttp介绍网络库一直是Android APP开发中至关重要的库,关系到加载速度,流量消耗等诸多问题。Android原生系统提供了HttpClient和HttpURLConnection两个网络库。相比HttpHttpClient,OKHttp性能更好,且API设计更加易用。相比HttpURLConnection,OKHttp功能更加强大。目前采用OKHttp方案的APP越来越多,搞懂它的底原创 2016-09-03 18:16:57 · 3848 阅读 · 10 评论 -
Glide源码分析4 -- 缓存,编解码和网络请求
1. 概述和核心类在Glide源码分析 – request创建与发送过程一文中,我们谈到request最终通过GenericRequest的onSizeReady()方法进行,其中调用了engine.load()方法去实际获取数据。本文主要讲述engine.load()之后发生的那些事,让大家能够对底层数据获取有个更清晰的认识。从这点也可以看出Glide设计分层的精妙。主要涉及的核心类如下1)Gen原创 2016-08-07 16:14:47 · 3630 阅读 · 0 评论 -
Glide源码分析3 -- 绑定Activity生命周期
1. 概述和核心类Glide中一个重要特性是Request可以随Activity或Fragment的onStart而resume,onStop而pause,onDestroy而clear,从而节约流量和内存,并且防止内存泄露,这一切都由Glide在内部实现了。用户唯一要注意的是,Glide.with()方法中尽量传入Activity或Fragment,而不是Application,不然没办法进行生命原创 2016-08-07 16:13:42 · 6683 阅读 · 8 评论 -
Glide源码分析2 -- request创建与发送过程
1. 概述和核心类使用Glide的一般形式为 Glide.with(context).load(url). placeholder(R.drawable.test).into(imageView)。 使用起来相当简单,大家有没有想过内部流程是怎么实现的呢?我是一个喜欢研究源码的人,抱着打破砂锅问到底的想法窥探了下Glide源码,发现这个流程主要与Glide的requests生成与发送过程有关。与原创 2016-08-07 16:12:27 · 2494 阅读 · 4 评论 -
Glide源码分析1 - 框架
Glide是由bumptech开发的一款Android图片加载库,得到了Google的大力推荐,并广泛应用于Android app开发中。Glide支持功能众多,代码量大,但模块分层清晰,相互独立,是一个非常经典的框架设计案例。读者不仅可以从源码中学到Glide加载图片的机理,也可以学到很多不错的设计模式案例。Glide的有如下优点原创 2016-08-07 12:18:53 · 1600 阅读 · 2 评论 -
JVM类加载与运行时优化
1. 类加载生命周期 a. 装载(load) i. 开始时机: 1) new实例化对象时,若类没有加载 2) 读取或设置一个类static字段,若类没有被加载。final除外,因为final字段的值已经在编译期放到了常量池中 3) 调用类的static方法 4) 反射调用类原创 2016-07-13 15:32:58 · 2964 阅读 · 1 评论 -
Java字节码与Dalvik字节码
1. JVM语言无关性JVM只与字节码关联,而不与Java语言直接关联。事实上,JRuby,Groovy等语言也可以由相应的编译器编译为字节码,然后由JVM解释执行。甚至可以自己写一个class字节码文件,然后由JVM来执行。2. class类文件结构任何一个class文件都对应着唯一一个类或接口的定义信息。class文件是一组8字节为基础单位的二进制流,各个数据项完全按照规范要求排列,中间原创 2016-07-13 12:40:46 · 2035 阅读 · 0 评论 -
JVM垃圾回收
1. What:哪些内存区域需要回收 a. 程序计数器,虚拟机栈,本地方法栈随线程而生,随线程而灭。栈中栈帧随着方法的调用和返回自动的入栈和出栈,并且栈帧需要多大在编译期就是可知的。因此这些区域的内存分配和回收是确定的,故不需要GC来参与。 b. 堆:对象和数组基本都在这个区域,是GC的主力 c. 方法区:无用的类型信息和const都是回收的目标,但一般他们是垃圾的概率不大,故原创 2016-07-12 17:33:46 · 894 阅读 · 0 评论 -
JVM内存区域
1. 运行时数据区 a. 程序计数器 pc i. 比较小,当前线程执行字节码的位置。分支,循环,异常处理,跳转,线程恢复都需要它 ii. 线程私有,故线程间互不干扰。 iii. 不会OOM,不需要GC b. Java栈 i. 线程私有,线程间不会干扰 ii. 存放Java方法的局部变量,入参等。原创 2016-07-12 16:22:16 · 1566 阅读 · 0 评论