- 博客(61)
- 资源 (1)
- 收藏
- 关注
原创 如何构建自己的支付系统
文章目录名词解释业务场景模块划分业务流程支付退款对账避坑指南名词解释第三方渠道:指支付宝、微信、银联、度小满等第三方金融平台;业务方:指自己的业务模块;支付单:支付单分为两,渠道支付订单号和商户订单号,其中渠道支付订单号是第三方渠道生成的订单,而商户订单号是业务方自己生成业务的标识,进行外部对账以渠道支付订单号为准,进行内部对账时,以商户订单号为准;退款单:与支付单对应,它会与原始支付单...
2020-05-01 16:08:42
1052
原创 Mybatis 源码学习(13)-DataSource
历史文章:Mybatis 源码学习(12)-资源加载数据源模块位于 org.apache.ibatis.datasource 包内,其中的核心类包括:DataSourceFactory 和 DataSource。数据源模块是一系列代码,它符合抽象工厂的构建方式,首先它提供了 DataSourceFactory 接口和 DataSource 接口,分别代表抽象工厂的工厂接口和工厂产品实现,并分...
2019-12-09 23:39:49
302
原创 Mybatis 源码学习(12)-资源加载
历史文章:Mybatis 源码学习(11)-日志模块Mybatis 中的资源加载依赖于 JVM 的类加载机制,在 JVM 中的类加载机制使用的双亲委派模式。默认情况下,JVM 中存在三种加载器:Bootstrap ClassLoader、Extension ClassLoader、System ClassLoader,我们也可以拓展实现用户自定义的类加载器 UserDefine ClassL...
2019-12-05 22:41:28
243
原创 Mybatis 源码学习(11)-日志模块
历史文章:Mybatis 源码学习(10)-类型转换(TypeAliasRegistry)Java 开发中常用的日志工具类包括Log4J、Log4J2、Apache Common Log、java.util.logging、Slf4j,这些工具的接口并不统一,为了提供统一的接口,Mybatis 对这些日志接口做了统一适配。Mybatis 的日志模块使用了适配器模式,其内部提供了统一的适配器...
2019-12-05 22:38:57
287
原创 Mybatis 源码学习(10)-类型转换(TypeAliasRegistry)
历史文章:Mybatis 源码学习(8)-类型转换(TypeHandler)TypeAliasRegistry 的逻辑比较简单,它负责为某个数据类型创建别名,之后在使用时可以使用别名引用该类。在 Mybatis 的 mapper.xml 文件中,一般会有返回值的类型,对于整型数值,既可以用 int 也可以用 integer,还可以用类的全限定名,这里就是用到了 Integer 的别名。Ty...
2019-11-30 16:38:01
199
原创 Mybatis 源码学习(9)-类型转换(TypeHandlerRegistry)
历史文章:Mybatis 源码学习(8)-类型转换(TypeHandler)定义 TypeHandler 后,Mybatis 还需要对这些 TypeHandler 进行管理,Mybatis 是通过 TypeHandlerRegistry 来实现 TypeHandler 的管理的。TypeHandlerRegistry 的初始化是在 Configuration 中,Configuration ...
2019-11-24 22:31:03
585
原创 Mybatis 源码学习(8)-类型转换(TypeHandler)
历史文章:Mybatis 源码学习(7)-反射工具(ObjectWrapper & MetaObject)JDBC 规范中定义的数据类型和 Java语言中的数据类型并非完全对应,因此需要在操作 Statement 时需要将 Java 类型转为 JDBC 类型,而处理 Result时,需要将JDBC 类型,转为 Java 类型。Mybatis 使用 TypeHandler 处理这种类型...
2019-11-24 22:30:32
183
原创 Mybatis 源码学习(7)-反射工具(ObjectWrapper & MetaObject)
历史文章:Mybatis 源码学习(6)-反射工具(MetaClass)MetaClass 可以通过反射来解析类级别类型信息,而 ObjectWrapper 是对对象的包装,可以通过字符串操作和查询对象的属性。ObjectWrapper 类继承关系如下,它提供了 BaseWrapper、BeanWrapper、MapWrapper 和 CollectionWrapper。BaseWrappe...
2019-11-20 22:50:44
583
原创 Mybatis 源码学习(6)-反射工具(MetaClass)
历史文章:Mybatis 源码学习(5)-反射工具(Property 工具)MetaClass 可以被用来解析任意 Class 对象的方法和字段,它对外提供了:findProperty、hasSetter、hasGetter、getSetterType、getGetterType 等方法判断属性以及对应的 get、set 方法是否存在。在 MetaClass 内部,使用了 Reflector...
2019-11-17 22:58:58
295
原创 Mybatis 源码学习(5)-反射工具(Property 工具)
历史文章:Mybatis 源码学习(4)-反射工具(ObjectFactory)Property 工具集包含 PropertyTokenizer、PropertyNamer、PropertyCopier 三个工具类,其中 PropertyTokenizer 用于符号解析,PropertyNamer 用于解析和判断属性名称,PropertyCopier 用于对象属性复制。PropertyTo...
2019-11-17 22:57:19
234
原创 动态替换Spring容器中的Bean
原因最近在编写单测时,发现使用 Mock 工具预定义 Service 中方法的行为特别难用,而且无法精细化的实现自定义的行为,因此想要在 Spring 容器运行过程中使用自定义 Mock 对象,该对象能够代替实际的 Bean 的给定方法。方案创建一个 Mock 注解,并且在 Spring 容器注册完所有的 Bean 之后,解析 classpath 下所有引入该 Mock 注解的类,使用 Mo...
2019-11-17 01:04:30
5178
原创 Mybatis 源码学习(4)-反射工具(ObjectFactory)
历史文章:Mybatis 源码学习(3)-反射工具(TypeParameterResolver)ObjectFactory 相对简单,它是一个接口,定义了如何创建 Mybatis 中的对象,在 Mybatis 的配置文件中,可以直接自定义 ObjectFactory 的接口实现类。Mybatis 默认提供了 ObjectFactory 的实现类:DefaultObjectFactory。O...
2019-11-11 22:46:31
149
原创 Mybatis 源码学习(3)-反射工具(TypeParameterResolver)
TypeParameterResolver 是用来解析类中字段、方法参数、方法返回值的工具类,它通过自身的静态方法,利用反射处理对应的类型,并转化为实际的 Type 类型。而 Type 类型是 java 程序中所有数据类型的基类,它包含原始类型,参数化类型,类型变量,数组类型和通配符泛型几种类型。TypeType 是所有类型的父接口,它的继承关系如下:Class:原始类型,Java 中的每...
2019-11-11 00:19:18
439
1
原创 Mybatis 源码学习(2)-反射工具(Reflector)
由于 JDK 提供的反射机制过于复杂,因此 Mybatis 对常用的反射机制做了封装,以简化反射 API,这部分封装代码在 org.apache.ibatis.reflection 包中。ReflectorReflector 主要用于解析一个 Class 对象,将其类型、构造函数、set方法、get 方法做解析,方便随时使用。这里的 get/set 方法解析,只根据方法进行解析,而不关系其中...
2019-11-05 23:17:41
325
原创 Mybatis 源码学习(1)-解析器模块
XPathXPath 是通过表达式在 XML 文件中选择节点的表达式语言,通过 XPath 可以将 XML 中的节点,通过特定的规则将 DOM 对象,转化为 Boolean、Double、String 等 Java 对象。简单的举例来说:给定 xml 文件内容为<foo> <bar/> <bar/> <bar/></foo...
2019-11-01 23:45:25
221
原创 使用Lombok @Builder注解导致默认值无效
@Builder注解导致默认值无效 使用Lombok注解可以极高的简化代码量,比较好用的注解除了@Data之外,还有@Builder这个注解,它可以让你很方便的使用builder模式构建对象,但是今天发现@Builder注解会把对象的默认值清掉。像下面这段代码,会导致对象的name属性变为null:public class BuilderTest { @lombok....
2018-06-28 08:19:26
11579
原创 Red Black Tree(红黑树)
当二叉平衡树在树高较高时,许多操作的代价较高,甚至比不过链表,此时可以采用红黑树。红黑树是许多平衡搜索树中的一种,可以保证在最坏情况下基本动态集合操作的时间复杂度为O(lg n)。红黑树有很多的应用,其中比较多的应用是各种类库中的Map,在Java中的TreeMap就是使用红黑树构建的,C++中的STL带的Map的结构也是红黑树构建的。红黑树的性质红黑树是一种二叉搜索树,它在每个节点上增加一个存储节点颜色信息的位,可以是RED或BLACK。由于颜色的约束,红黑树保证没有一条路径比其他路径长2倍,因此近似
2016-09-07 22:01:25
998
原创 Java中的类加载机制
在Java虚拟机中,类在JVM中的生命周期为:加载、验证、准备、解析、初始化、使用和卸载几个阶段。一般类的主动加载会有以下情况:遇到new、getstatic、putstatic、或invokestatic这4条字节码(一般为new对象时,读取设置类静态字段时,调用类的静态方法时);使用java.lang,reflect包的方法进行反射时;初始化某个类,其父类会首先被初始化;拥有main方法所在的
2016-09-07 18:25:38
505
原创 Java中的垃圾回收
对象是否存活引用计数算法:一般判定对象是否存活的方式是通过引用计数器来记录和判定的。其过程大概是记录一个对象被引用的次数,当增加这个对象的引用时就将引用次数加1;当一个引用失效时就将引用次数减1,当对象的引用次数为0时就回收这个对象。这种方式简单且方便(有许多语言也都使用了这种方式,如Python),但是它不能解决对象间的循环引用问题。可达性分析算法:Java中是通过可达性分析(Reach
2016-09-06 22:03:33
638
原创 ASM(字节码处理工具)
ASM是一种Java字节码生成和分析的框架,我们可以用它通过操作二进制的方式来修改现成的类或者动态生成class文件。ASM不仅提供了和其他字节码生成框架相类似的功能,此外它还关注框架的易用性和性能。ASM的源代码中包含了若干packages:org.objectweb.asm:是项目的核心包,它提供了ASM的访问API,并且提供了ClassReader和ClassWriter来读取和
2016-08-26 23:31:25
6549
原创 Java中的集合(Map)
标准库中包含了几种Map的基本实现,包括:HashMap、TreeMap、LinkedHashMap、WeekHashMap、ConcurrentHashMap、IdentityHashMap。它们都有同样的基本接口Map,但是行为特性各不相同,这表现在效率,键值对的保存及呈现次序、对象的保存周期、映射表如何在多线程程序中工作和判定“键”等价的策略等方面。Map可以将键映射到值。一个映射不能包含重复的键;每个键最多只能映射到一个值。Map 接口提供三种collection 视图,允许以键集、值集或键-值映
2016-08-25 22:23:00
3573
1
原创 Java中的集合(List和Set)
Java容器类主要是为了“保存对象”,并将其划分为两个不同的概念:Collection,独立元素的集合,这些元素都服从一条或多条规则,如List必须按照插入顺序保存元素,Set不能有重复元素,Queue按照排队规则来确定对象的顺序。Map形成一组“键值对”对象,允许你使用键来查找值,故也被称为关联数组。本篇文章主要讲List和Set的实现细节和具体的操作。
2016-08-24 22:46:29
2936
1
原创 Java中的注解(annotation)
注解(也被称为元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些信息数据。注解在一定程度上是把元数据和源代码文件结合在一起,而不是保存在外部文档中。它可以使得我们能够让编译器来测试和验证格式,存储有关程序的额外信息。注解还可以生成描述符文件,甚至或是新的类定义,并且有助于减轻些“样板”代码的负担。注解是在实际的源代码级别保存所有的信息,而不是某种注释性的文字,这使得代码更整洁且便于维护。
2016-08-23 20:11:57
1654
原创 Java中的RMI(远程方法调用)
RMI(Remote Method Invocation,远程方法调用)是从java1.1开始实现的,它大大增强了Java开发分布式应用的能力。RMI对接口有着强烈的依赖,在需要创建一个远程对象的时候,我们通过传递一个接口来隐藏基层的实施细节,所以客户得到远程对象的一个句柄时,它们真正得到的是接口句柄,然后本地代码通过接口操作远程对象。通过RMI编写程序可以非常方便的实现分布式Java应用程序。
2016-08-23 19:42:46
11289
原创 Java中的IO系统
Java I/O系统中的类非常复杂,而且因为使用了装饰器模式,很容易造成使用多种组合方式都可以达到相同的目的,故很容易产生疑惑。Java中的I/O系统大部分都在java.io包中,并且可以分为两类:针对字节流的I/O;针对字符流的I/O。并且每种I/O又分为输入流和输出流。在处理Java中的I/O时主要关注数据格式要怎么处理和数据要以什么方式传输,这两个问题。
2016-08-22 22:23:25
668
原创 Java中的NIO
Java1.4之后提供了java.nio包,里面包含了新的I/O库,通过使用这个nio包可以提高速度。速度的提高来自于,它的结构接近操作系统执行I/O的方式,它的核心操作源自于通道和缓冲器。通道是和I/O系统内部交互的地方,所有的数据都要通过缓冲器交给通道,通道会自动帮你和底层进行存储或取出。而且,唯一直接能够与通道交互的缓冲器是ByteBuffer。
2016-08-21 14:25:49
1301
1
原创 Java中的对象序列化
Java的对象序列化将那些实现了Serializable接口的对象转换成一个字节序列,并能够在以后将这个字节序列完全恢复为原来的对象。这一过程甚至可以通过网络进行,这意味着序列化机制能自动补弥不同操作系统之间的差异。“持久化”意味着一个对象的生存周期并不取决于程序是否正在执行,它可以生存于程序的调用之间。对象序列化的概念加入到语言中是为了支持两种主要特性。一是Java的远程方法调用(Remote Method Invocation,RMI),它使存活于其他计算机的对象使用起来就像是存活于本机上一样。二是对
2016-08-21 14:15:38
481
原创 Binary Search Tree(二叉搜索树、二叉查找树、二叉排序树)
搜索树数据结构支持许多动态几何操作,包括SEARCH、MININUM、MAXINUM、PREDECESSOR、SUCCESSOR、INSERT和DELETE等。因此,我们可以使用一个搜索树作为字典或者优先队列。二叉搜索树上的基本操作所花费的时间与所花费的时间与这棵树的高度成正比。对于有n个结点的一棵完全二叉树来说,这些操作的最坏运行时间为Θ(logn)。然而如果这棵树是一条n个结点构成的线性链表(最坏情况下),那么同样的操作就要花费Θ(n)的最坏运行时间。
2016-08-20 22:32:09
1296
原创 算法学习—动态规划
动态规划(dynamic programming)是通过组合子问题来求解原问题的方法,它倾向于解决子问题重叠的情况,即不同子问题具有公共的子问题。从这方面来看,动态规划都可以用递归来实现,但是递归是从上到下的思路进行处理的,也就是说递归是从完整的问题,逐次向子问题求解的过程,但是动态规划却是从规模最小的子问题开始,向上逐步求解,求解过程中保存这些小规模的子问题作为求解大问题的依据,并最终求出结果。例如求解斐波那契数列,使用递归的思路是从f(n)依次向下求解f(n-1)和f(n-2),但是使用动态规划的思路
2016-08-20 21:41:48
1740
原创 生产者消费者Java实现
对于生产者消费者模式来说,通常可以用java.util.concurrent包中的ArrayBlockingQueue来实现,但是有的时候不让用concurrent,必须自己手工实现。编写生产者消费者有多中方式,一种是当条件不满足时就抛出异常,一种是通过轮询或休眠的方式,当条件不满足时进行循环,直到条件满足为止。但是还有更好的方式是,当条件不满足时可以让线程等待,如果是生产者产品过多,则让生产者等待,如果消费者消费过快,则消费者等待生产者生产。
2016-08-19 19:37:54
1122
原创 八大内部排序算法总结
各种内部排序算法的简单总结:插入排序:直接插入排序插入排序:Shell排序选择排序:直接选择排序选择排序:堆排序交换排序:冒泡排序交换排序:快速排序归并排序基数排序
2016-08-18 21:37:45
725
原创 Java6中与Synchronized相关的锁机制
JDK1.6提供了大量的锁优化技术,其中包括适应性自旋(Adaptive Spinning)、锁消除(Lock Elimination)、轻量级锁(Lightweight Locking)和偏向锁(Biased Locking)等。通过使用这些方法对Synchronized进行了虚拟机级别的锁优化,从而提高了Synchronized的使用效率。
2016-08-18 15:58:29
1410
原创 二十三、访问者模式Visitor(行为型)
表示一个作用于某个对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。使用访问者模式时,我们可以将每个类中的相关操作包装在一个独立的对象中,并在使用时将对象传递给当前访问的元素,当一个元素“接受”该访问者时,该元素向访问者发送一个包含自身类信息的请求,该请求同时也将该元素本身作为一个参数,然后访问者将为该元素执行该操作。一般情况下,Visitor模式需要定义两个类层次:一个对应于接受操作的元素,另一个应用于定义对元素的操作的访问者。当需要增加新的操作时,只需要添加新的
2016-07-30 22:03:15
572
原创 二十二、模板方法模式Template Method(行为型)
定义一个算法的骨架,将其中的某些步骤的实现延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。模板方法可以使用一些抽象的操作定义一个算法,而子类重定义这些操作以提供具体的行为。通过使用抽象操作定义算法中的某些步骤,模板方法确定了它们的先后顺序,子类再实现这些抽象方法,这样一个完整的算法就完成了。模板方法适用于,算法中具有某些不变部分,并可以将不变的行为交给子类来实现,或者是子类中的公共行为可以被提取到公共父类中,以避免代码重复。
2016-07-30 22:02:31
367
原创 二十一、策略模式Strategy(行为型)
定义了一系列的算法,把它们一个个封装起来,并且使它们可相互替换。策略模式使得算法独立于它的Client的变化而变化。策略模式可以帮助我们处理,当我们需要在不同的情况下使用不同的算法时的情况。策略模式适用于,许多类只有行为存在差异,或者需要使用一个算法的不同变体时。但是策略模式也有一些缺点,比如,Client必须了解不同的策略之前的差别,容易造成Context和Strategy之间的耦合,增加了对象的数量等。
2016-07-30 22:01:30
328
原创 二十、状态模式State(行为型)
允许一个对象在其内部状态改变时改变它的行为,这种改变看起来似乎是修改了它的类本身。就像进行TCP连接时,TCP连接的状态都会经过一系列的变化,当从一个状态变为另一个状态时,它的功能就可能发生变化。
2016-07-30 22:00:41
352
原创 十九、观察者模式Observer(行为型)
观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知,并被自动更新。将一个系统分割成一系列相互协作的类有一种常见的副作用,需要维护相关对象间的一致性,我们不希望为了维护一致性而使各种类紧密耦合,这样会降低它们的可重用性。观察者模式可以描述一个对象改变时,与之相关的对象状态也可以被动更新。在观察者模式中,一个Observer可以订阅任意数量的Subject,一旦Subject的状态发生改变的时候,所有的观察者都会得到通知。
2016-07-29 19:34:29
560
原创 十八、备忘录模式Memento(行为型)
在不破坏封装性的前提下,捕捉一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原来保存的状态。为了允许用户取消不确定的操作,或从错误中恢复过来,需要实现检查点和取消机制,而要实现这些机制,你必须事先将状态信息保存在某处,这样才能将对象恢复到它们先前的状态。
2016-07-29 19:33:42
304
原创 十七、中介者模式Mediator(行为型)
中介对象可以封装一系列的对象交互,它可以使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。在进行面向对象设计时,一般倾向于将系统分割成许多对象,这样可以增加复用性,但是这样做会导致对象的关系会非常复杂。中介者可以将这些集体行为封装起来,充当控制和协调这组对象交互的角色,从而使得这些对象之间不再有显式的相互引用,它们只知道中介者,从而减少了相互连接的数目。
2016-07-29 19:31:52
398
原创 十六、迭代器模式Iterator(行为型)
提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示。迭代器模式的关键思想是将对聚集对象的访问和遍历从队列对象中分离出来,并放入一个迭代器对象中,迭代器类定义了一个访问该聚集对象的接口。另外,迭代器和聚集对象是聚合在一起的,而且客户对象必须知道遍历的是哪个具体的聚集对象,以及它的结构是什么,这可以通过多态来实现。使用迭代器模式时分为两种迭代形式:外部迭代,由客户来控制迭代;内部迭代,由迭代器控制迭代。使用外部迭代是比较灵活的,但是需要外部客户主动控制迭代的过程。
2016-07-29 19:31:21
453
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人