- 博客(501)
- 资源 (16)
- 收藏
- 关注
原创 虚拟数字键盘
虚拟数字键盘背景移动端的浏览器中,input元素的自动聚焦并弹起系统键盘很难做到统一,一是IOS系统下的浏览器,非真实的用户交互,是无法弹起系统键盘的,通过js模拟也不行。二是某些浏览器下,input的输入光标会没有,使得用户体验不佳。目标1、进入页面时就自动聚焦到input上,并弹出数字键盘。2、input输入带光标3、提供通用的配置入口4、额外的校验逻辑,例如正确的金额格式校验...
2019-01-18 16:01:21 1386
原创 简单好用的api mock工具
在前后端人员的协作开发中,如果你是后端开发人员,想模拟前端调用,可以使用PostMan发送请求,如果是你是前端人员,可能需要使用一些js框架来拦截请求,模拟后台返回报文。如果你不熟悉这些框架,又懒得去学的话,这里推荐一个简单好用的api mock工具。 使用方法1、下载工具 去资源页下载api-mock-util-v1.0.2工具,是一个可执行的jar包。...
2018-08-10 11:14:13 10786 9
原创 基于layui2.x的通用后台管理系统
一、概述 之前的spring集成系列文章中spring集成shiro权限控制一文最后提到了通用的mvc框架和前后端分离方案。在准备前后端分离方案demo的时候,纠结于选择哪个前端框架。对于后端开发人员来说,Angular和Vue都过于专业化了,需要额外的精力去学习。这个时候刚好看到了layui框架(http://www.layui.com/),惊叹于它的优美和易用,而且是基于jQu...
2018-01-15 09:58:36 58890 74
原创 mybatis是如何集成到spring的之托管mapper接口
mybatis集成到spring最重要的两个配置分别是SqlSessionFactoryBean和MapperScannerConfigurer,其中MapperScannerConfigurer帮助我们把mapper对象托管到spring。使得我们没有定义任何Mapper的Bean,却可以通过@Autowired进行注入,大大简化了我们开发的难度,让我们把重心放在了sql逻辑本身。
2023-05-21 01:08:03 1067
原创 mybatis是如何集成到spring的之SqlSessionFactoryBean
我们注册的是SqlSessionFactoryBean这个bean,为什么却说SqlSessionFactory也成为了spring的bean呢?我们的SqlSessionFactoryBean还实现了FactoryBean这个接口。Spring 中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean 即 FactoryBean。FactoryBean跟普通Bean不同,其返回的对象不是指定类的一个实例,而是该FactoryBean的getObject方法所返回的对象。
2023-05-13 16:17:57 1950 1
原创 ReentrantLock原理剖析
ReentrantLock是最常用的锁API,在线程池ThreadPoolExecutor、阻塞队列LinkedBlockingQueue,同步工具CyclicBarrier等中都能看到它的身影。掌握好ReentrantLock的原理,可以让我们更加清楚基于它的实现的其他工具类的实现原理。ReentrantLock实现了类似Syncronized的同步能力,但它还支持了公平锁的能力。根据公平和非公平需要,ReentrantLock持有相应的公平或者非公平的同步器。
2023-05-03 13:07:27 879
原创 线程池核心线程是如何保持住的?
通过对线程池的学习,我们知道了线程池的执行流程:1、任务到来时,看CORE线程数有没有满,如果没有满则新创建线程处理。2、如果core线程数量满了,则放入队列中。3、如果队列也满了,则看看线程数量是否达到了maxPoolSize值,如果没有则创建新线程处理。4、如果已经达到了maxPoolSize的值,则根据拒绝策略处理任务。然后我们可以回答这些问题:1、核心线程池是如何保持住的?通过workQueue.take()方法对线程进行阻塞,让我们线程保持住不被数量-1而回收掉。
2023-04-29 16:27:53 3119 5
原创 聊聊synchronized关键字
接触java并发编程,用得最早最多的大概就是这个synchronized关键字了,synchronized是基于jvm实现的,不同于juc包的实现。发现想要讲好synchronized,并不容易。这里权当作抛砖引玉了。synchronized基本用法synchronized关键字可用于修饰方法和代码块。我们举例说明:假设我开了一家宠物店,客人可以到店里来撸猫,店子比较小每日只提供一只猫撸,猫...
2020-04-21 22:03:17 406 1
原创 Mybatis插件机制探究及延伸思考
文章目录前言使用原理分析延伸思考1-关于plugin方法2-责任链?基于jdk动态代理的双向责任链总结前言Mybatis提供了插件机制,可以让我们介入到底层执行的一些流程,例如SQL执行前打印下SQL语句。这里的插件,在mybatis里面实际上是拦截器。在深入探究之前,先看看如何使用,然后再分析原理,最后会提一下笔者从里面得到的一些启发。使用首先我们需要在mybatis的配置文件(myba...
2020-04-16 18:38:06 349
原创 利用JRebel进行远程热部署调试
一、背景 我的工作中有些页面调试十分麻烦,例如一个支付页面,调试遇到的难点就有: 1、工程依赖了Apollo,如果要本地调试,需要本地添加Apollo的相关Java参数。 2、进入到支付页面前需要对用户做OAUTH,有个回调地址需要在微信端配置,但是只能配一个地址。如果本地要能正常跑起来,需要在Nginx配一些代理。 3、由于需要做OAuth的原因,这个页面无法在浏览器通过...
2020-03-06 16:24:31 1391
原创 RocketMQ Consumer如何获取并维护消费进度?
背景Cosumer消费消息,一般是如下几个步骤:发送获取消息请求,查找消息,消息过滤,负载均衡,消息处理,回发确认。限于篇幅,这篇文章主要介绍Consumer是如何发送获取消息请求的,以及RocketMQ基于长轮询的推模式实现。由于以上几个步骤都是紧密相连的,可能会出现互相穿插。从何处开始消费?...
2020-01-21 11:43:49 3873
原创 RocketMQ Consumer如何订阅消息的?
在配置Consumer的时候,通常会有这么一行代码: /** * 订阅指定topic下所有消息<br> * 注意:一个consumer对象可以订阅多个topic */ consumer.subscribe("test_url", "*");这行代码表示该consumer订阅了test_url这个topic下面的所有类型消息。这样之后就可以顺利接收到test_u...
2020-01-10 15:52:48 6277
原创 RocketMQ如何构建ComsumerQueue的?
前言RocketMQ的消息都是按照先来后到,顺序的存储在CommitLog中的,而消费者通常只关心某个Topic下的消息。顺序的查找CommitLog肯定是不现实的,我们可以构建一个索引文件,里面存放着某个Topic下面所有消息在CommitLog中的位置,这样消费者获取消息的时候,只需要先查找这个索引文件,然后再去CommitLog中获取消息就 OK了。这个索引文件,就是我们的Comsumer...
2020-01-02 12:28:50 2778 4
原创 关于pre换行的一点探究
背景换行是很常见的需求,一般word-break搭配overflow属性就可以很轻松的实现,例如:<html lang="zh"><head> <style type="text/css"> .log_wrap{ overflow-x:hidden; overflow-y:auto; word-break:break-all;...
2019-12-05 10:49:35 336
原创 避免360浏览器极速模式自动填充表单
问题在表单里面有API密钥和证书密钥两个字段,刚好一个type=text,一个type=password,360以为是登录用户名和密码字段,进行了自动填充,如下所示:解决方案网上解决方案有很多,有的可行,有的不行。我试了好几种,现记录下成功的这一种。方法就是:将被自动填充的type=text那一个input的readonly设置为true,然后页面初始化的时候,延时一小段时间,再将其设置为...
2019-11-27 16:03:12 831
原创 Netty在RocketMQ中的应用----服务端
RocketMQ中角色有Producer、Comsumer、Broker和NameServer,它们之间的通讯是通过Netty实现的。在之前的文章RocketMQ是如何通讯的?中,对RocketMQt通讯进行了一些介绍,但是底层Netty的细节涉及的比较少,这一篇将作为其中的一个补充。服务端启动 ServerBootstrap childHandler = this.s...
2019-11-06 15:52:19 544
原创 Netty在RocketMQ中的应用----客户端
RocketMQ中角色有Producer、Comsumer、Broker和NameServer,它们之间的通讯是通过Netty实现的。在之前的文章RocketMQ是如何通讯的?中,对RocketMQt通讯进行了一些介绍,但是底层Netty的细节涉及的比较少,这一篇将作为一个补充。Netty客户端启动配置Bootstrap handler = this.bootstrap.group(this....
2019-11-06 10:41:27 1047 1
原创 微信支付宝页面点击返回后关闭
需求背景在支付完成页面后,如果用户点击返回按钮,会返回到继续支付的页面。既然已经完成支付了,那么在用户点击返回按钮之后,就可以关闭页面了,这才是合理的做法。所以我们的目的就是,监听用户的页面返回事件,然后关闭页面。监听返回事件js里面有一个popstate事件,当页面返回时会触发这样一个事件。微信支付宝里,直接的监听该事件,在返回按钮点击时,并不能真正的触发popstate事件。需要通过pu...
2019-10-30 15:51:32 1092
原创 window.name跨域通讯小坑一记
工作中有这么一个需求,在支付完成之后,延迟3秒跳转到商户的广告页面。在广告页面通过返回按钮,可以再次返回到支付完成的详情页面,但此时延迟3秒后不会再次跳转到商户广告页面。很明显,需要存一个标记,表示是否已经跳转过了。当时觉得window.name应该就可以胜任这个任务。window.name我们在js里面随时可以获取window对象,window对象有一个name属性,如下所示:这个na...
2019-09-17 15:51:30 423
原创 RocketMQ消息存储结构简介--CommitLog
RocketMQ消息存储是整个系统的核心,直接决定着吞吐性能和高可用性。RocketMQ存储消息并没有借助oracle、mysql等关系型数据库,而是直接操作文件。借助java NIO的力量,使得I/O性能十分高。当消息来的时候,顺序写入CommitLog。为了Consumer消费消息的时候,能够方便的根据topic查询消息,在CommitLog的基础上衍生出了CosumerQueue文件,存放了...
2019-09-09 15:25:33 3929 1
原创 RocketMQ发送消息如何选择消息队列?
Producer发送消息的主要流程是验证消息---->查找Topic路由---->选择消息队列—>发送消息。验证消息没什么好说的,很简单。Topic路由的获取和保存、发送消息,之前的文章都有部分涉及,就不再赘述。这里我们对消息队列的选择做一个简单的展开。首先,要澄清一个误会。这里的选择消息队列发送消息,并不是真的往某个队列发送消息。RocketMQ的消息只存在一个叫Commit...
2019-09-04 15:40:42 3100 1
原创 ByteBuffer介绍
为什么会在RocketMQ系列里面参杂一篇ByteBuffer的文章呢?因为RocketMQ存储消息,是存储在文件中的,而且刚好使用的是ByteBuffer。这个属于Java NIO的内容,用到的比较少,如果像我一样没有相关的知识做铺垫,强行看RocketMQ消息存储相关的代码会比较头疼。为了减少学习难度,这里很有必要先介绍一下ByteBuffer相关的知识。...
2019-08-30 15:25:39 1060
原创 Producer如何获取Topic路由信息
Producer要发送Message,肯定需要先知道Topic路由信息,这样才能找到提供Topic服务的Broker master结点并发送Message。之前的文章Topic是如何创建和保存的,我们知道了Topic在Broker保存了一份,然后Broker定期向NameSrv注册Broker信息。这样NameSrv就存有所有Topic路由信息。因此Producer要发送消息,肯定需要从NameS...
2019-08-27 11:41:48 873 1
原创 RocketMQ如何维持心跳
首先放上RocketMQ网络结构图,如下所示:Producer与NameSrv随机建立长连接,定期从NameSrv获取topic路由信息。然后Producer还与Broker的Master结点建立长连接,用于发送消息。此外Producer还与Master维持了一个心跳。Conumser与NamseSrv随机建立长连接,定期从NameSrv获取topic路由信息。然后Consumer还与Bro...
2019-08-26 19:54:37 3927
原创 RocketMQ是如何通讯的?
前言RocketMQ作为一个分布式消息中间件,通讯肯定是必不可少的。参与通讯的角色包括:NameSrv,Broker,Producer和Consumer,另外Broker Master和Slave结点之间也有通讯。RocketMQ的通讯基于Netty,在其基础上做了一层简单的封装。大致的通讯架构如下所示:理解的这个框架图里的组件,也就理解了通讯的整个过程。通讯载体RemotingComma...
2019-08-23 16:51:56 1581
原创 RocketMQ Topic是如何注册和保存的
TopicTopic用于标识一些消息的分类,例如订单消息,通知消息。RocketMQ Producer发送消息,Consumer接收消息,Topic都是绕不过去的话题,消息就是围绕Topic组织的。Topic存储在NameSrv,Producer从NameSrv获取Topic的路由信息,找到broker,然后发送消息至broker。Consumer同样从NameSrv获取Topic路由信息,找到...
2019-08-19 11:15:21 2899
原创 CentOS 7使用RocketMQ mqadmin命令工具报错
问题描述我在CentOS 7上安装好RocketMQ之后,使用mqadmin创建topic,命令如下:./mqadmin updateTopic -n 192.168.77.129:9876 -c DefaultCluster -t test然后报错信息如下:org.apache.rocketmq.tools.command.SubCommandException: UpdateTopi...
2019-08-13 10:42:12 3009
原创 策略模式与消除If-else
策略模式策略模式是很常见的一种设计模式,将具体的算法封装起来,可以平等替换,避免客户端过多的设计业务逻辑。网上有很多讲策略模式的文章,都很好。但也有一些文章强行将策略模式、状态模式和消除if-else联系起来,这是不对的。策略模式只是封装了各自算法逻辑,使其可以自由替换,如何选择仍然需要客户端来决定。举个简单的会员充值的例子,初级会员充值100得100,中级会员充值100得150,高级会员充值...
2019-08-09 16:26:16 845 3
原创 flex布局导致ellispsis失效
问题描述之前的文本超过长度省略文章中,讲到了如何通过CSS控制文本超过长度省略。但是在flex布局中,ellispis却失效了。举例说明:文档结构如下:<div class="container"> <div class="div_1"> </div> <div class="div_2"> <span id="conte...
2019-08-08 19:14:43 1567 2
原创 如何判断ellispsis生效了
主要内容要让文本超过长度后,截取显示并附上省略号,可以通过如下的css代码实现: text-overflow: ellipsis; overflow: hidden; white-space: nowrap; width:100px;有时候,我们需要根据文本是否省略做一些别的事情,例如显示一个展开按钮。现在是CSS控制文本省略了,如何检测到呢?废话不多说,直接通过文本元素的clie...
2019-08-07 16:42:52 1913
原创 jsp页面禁用缓存
A页面跳转到B页面后,按返回按钮,返回页面A后并没有继续处理,而是卡住了,原因是jsp页面被浏览器缓存了。因此需要禁用Jsp页面缓存。正确的做法:<%@ page contentType="text/html;charset=UTF-8" %><% response.setHeader("Pragma", "No-cache"); resp...
2019-08-02 10:32:18 1034
原创 Dubbo-Monitor安装后无法访问
安装步骤说明Dubbo-Monitor安装比较简单,下载好包之后,解压,进入到conf目录,编辑dubbo.properties文件:dubbo.container=log4j,spring,registry,jettydubbo.application.name=simple-monitordubbo.application.owner=#dubbo.registry.address=...
2019-07-29 19:01:11 523
原创 Apollo加载配置小坑一记
公司的配置中心使用的是携程的Apollo配置中心,现在基本上所有的配置文件都迁移到了Apollo里面。Apollo的使用非常方便,实时生效,不需要重启应用。但是有个缺点,就是对配置没有进行校验,如果配置格式或者类型有问题的话,就会抛异常。鉴于此,一些逻辑上的校验就得自己做。例如对下载的账单要进行分割,这个大小不能小于1MB。我在配置的set方法里面做了一点简单的校验,例如账单分割单位billCu...
2019-07-12 16:15:20 2416 2
原创 实现输入框自带清除按钮
输入框自带清除按钮是很常见的需求了,网上有很多方案,最基础的是原生实现input和清除按钮,然后绑定一大堆事件,此种方案非常原始,而且复用性极差。稍微好点的方案有基于bootstrap和jQuery的,将input和清除按钮集成起来,但样式依赖bootstrap,加重了文件引入数,而且很容易有jQuery版本不兼容的问题。这里提供一个插件,仅依赖jQuery,我们实现的功能有:1、以一种很简单的...
2019-05-20 19:12:59 2728
原创 LockSupport原理
LockSupport是一个非常基础而重要的类,它为java并发包里的锁和同步类提供了线程阻塞原语。没有它也就没有AQS,更没有上层的各类锁实现(例如ReentrantLock),同步器(例如CountdownLatch),阻塞队列等。LockSupport提供的都是静态方法,例如:public static void park();public static void unpark(Th...
2019-05-08 17:35:59 1263
原创 AtomicBoolean原理
AtomicBoolean是一个原子boolen类,用于高并发场景下的标记,例如某个只需初始化一次的服务:public class SomeService { private String name; private AtomicBoolean initialized = new AtomicBoolean(false); public String getName(...
2019-05-07 15:34:23 1146
原创 关于LongAdder的一点思考
LongAdder是jdk 1.8引入的一个类,宣称比AtomiLong更高效。它内部有一个基本数base和一个cell数组,在高并发的情况下各个线程将值存放在了数组中,在低并发的情况下直接在一个base数上做计算,取值的时候把基本数和cell数组中的值做累加返回。其实看到取值的时候我是懵的,取值的代码如下: public long sum() { Cell[] as = ce...
2019-05-06 10:31:03 510
原创 手写一个简单的线程池
多线程的引入,可以大大增强系统的并发能力,但是创建一个线程的开销是很大的,频繁的创建和销毁线程反而使得我们的系统在高并发时性能急剧下降。如果线程用完了,先不着急销毁,有下个任务来了,再重复利用,是不是就好多了。线程池就是这样做的,当一个新任务到来的时候,线程池会找到一个空闲的线程来执行任务。如果线程池里的线程都用完了,那么线程池会根据将任务加入到一个队列中去等待。当队列也满了,线程池会根据要求创建...
2019-04-25 19:29:53 1465 2
原创 Quartz定时任务过期处理策略
由于某种原因,例如应用停掉,导致定时任务错过了本该执行的时间点,这就是定时任务过期。对于过期的定时任务,我们需要基于某种策略对其进行处理。过期策略在Trigger接口中定义了两种过期策略, public static final int MISFIRE_INSTRUCTION_SMART_POLICY = 0; public static final int MISF...
2019-04-23 16:46:02 5358
dubbo分布式应用日志追踪
2018-09-11
DelegatingFilterProxy示例
2018-08-03
手写DOM事件模型
2016-04-29
位置分享APP项目源码
2016-04-14
ffmpeg的tutorial中文版
2015-05-21
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人