Spring
未读
写在前面的话,当前文章共有两部分,大览全局
Spring源码分析
SpringBoot的启动流程
Spring源码分析AnnotationConfigApplicationContext反推猜测应该完成什么?
生成bean对象 -> 创建beanFactory (bean工厂)
BeanDefinition类 (加载bean信息, 通过注解得来的信息) -> 注解配置解析器AnnotationBeanDefinitionReader类
AnnotationBeanDefinitionReader中读取到不同的注解,有一系列的注解解析器去解析不同的注解
类路径扫描器 ClassPathBeanDefinitionScanner
系统属性扫描器 …
深入AnnotationConfigApplicationContext注解
123456789101112131415public AnnotationConfigApplicationContext(Class<?>... componentClasses) { // 配置类可以有多 ...
段落文本 p标签语法配置参数样式预览示例源码1{% p 样式参数(参数以空格划分), 文本内容 %}
字体: logo, code
颜色: red,yellow,green,cyan,blue,gray
大小: small, h4, h3, h2, h1, large, huge, ultra
对齐方向: left, center, right
彩色文字在一段话中方便插入各种颜色的标签,包括:红色、黄色、绿色、青色、蓝色、灰色。
超大号文字文档「开始」页面中的标题部分就是超大号文字。Volantis
A Wonderful Theme for Hexo
123456- 彩色文字 在一段话中方便插入各种颜色的标签,包括:{% p red, 红色 %}、{% p yellow, 黄色 %}、{% p green, 绿色 %}、{% p cyan, 青色 %}、{% p blue, 蓝色 %}、{% p gray, 灰色 %}。- 超大号文字 文档 ...
Spring
未读
前言: 当前章节不会像SpringBoot源码分析篇章一样大篇幅的列举大量源码, 仅仅列举部分源码
负载均衡依赖首先需要导入LoadBalance依赖
12345<!--LoadBalanced--><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>
逐步追踪依赖通过该starter追踪找到依赖jar包中只有一个pom文件, 在pom文件中找到LoadBalance的真正依赖
123456<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-loadbalancer</artifactId> ...
Spring
未读SpringBoot笔记持续更新中!
SpringBoot发布者订阅者样例场景: 我们需要在用户注册后 给订阅的用户推送消息(例如前100名注册的 系统自动发放徽章等)
12345678@Override@Transactional // 保证事件和用户注册的一致性public Long register(User insert) { boolean save = userDao.save(insert); // 用户注册的事件 -> 谁订阅就给谁发送通知 (1.Mq 2.ApplicationEventPublisher) applicationEventPublisher.publishEvent(new UserRegisterEvent(this, insert)); // this事件订阅者,发送端 return insert.getId();}
这个时候我们可以采用Spring的推送事件ApplicationEventPublisher, 其中除此之外我们还可以采用MQ进行同等操作
消息发布者 Event事件
...
DubboDubbo官网 Dubbo 文档 | Apache Dubbo
了解 Dubbo 核心概念和架构
以上是 Dubbo 的工作原理图,从抽象架构上分为两层:服务治理抽象控制面 和 Dubbo 数据面 。
服务治理控制面。服务治理控制面不是特指如注册中心类的单个具体组件,而是对 Dubbo 治理体系的抽象表达。控制面包含协调服务发现的注册中心、流量管控策略、Dubbo Admin 控制台等,如果采用了 Service Mesh 架构则还包含 Istio 等服务网格控制面。
Dubbo 数据面
。数据面代表集群部署的所有 Dubbo 进程,进程之间通过 RPC 协议实现数据交换,Dubbo 定义了微服务应用开发与调用规范并负责完成数据传输的编解码工作。
服务消费者 (Dubbo Consumer),发起业务调用或 RPC 通信的 Dubbo 进程
服务提供者 (Dubbo Provider),接收业务调用或 RPC 通信的 Dubbo 进程
Dubbo 数据面从数据面视角,Dubbo 帮助解决了微服务实践中的以下问题:
Dubbo 作为 服务开发框架 约束了微服务定义 ...
刮开看看:此篇文章用于总结在聊天项目中学习到的点
游标翻页游标翻页应对复杂变换的列表
深翻页问题我们在一般的后端开发场景中,比如管理系统,常常都会有分页条。她可以指定一页的条数以及快捷的调整页码。
现在我们假如前端想查看第11页的内容,传的值为 pageNo=11,pageSize=10
那么对于数据库的查询语句就是:
1select * from table limit 100,10
其中100代表需要跳过的条数,10代表跳过指定条数后,往后需要再取的条数。
对应就是这样的一个效果,需要在数据库的位置先读出100条,然后丢弃。丢弃完100条后,再继续取10条选用。
那么假如我们需要查询到100000条后的10条数据, 那么前面的是不是都被没用的丢弃了?
我们经常需要定时任务全量去跑一张表的数据,普通翻页去跑的话,到后面数据量大的时候,就会越跑越慢,这就是深翻页带来的问题。
游标翻页解决深翻页问题游标翻页可以完美的解决深翻页问题,依赖的就是我们的游标,即cursor。针对mysql的游标翻页,我们需要通过cursor快速定位到指定记录,意味着游标必须添加索引 ...
分布式锁声明式分布式锁对于样例代码,很容易看出来,这是一个声明式的分布式锁实现,复用性很差,下次还需要用到分布式锁还需要像这样写
123456789101112131415161718192021222324252627282930313233343536373839@Autowiredprivate RedissonClient redissonClient;@Autowiredprivate UserBackpackDao userBackpackDao;@Overridepublic void acquireItem(Long uid, Long itemId, IdempotentEnum idempotentEnum, String businessId) { String idempotent = getIdempotent(itemId, idempotentEnum, businessId); // 根据幂等号 构造分布式锁 RLock lock = redissonClient.getLock("acquireItem" + ...
项目遇到需要异步执行的逻辑,那么就到线程池了
需求分析需求:1. 异步刷新我们的token(续期)
为了减少系统的开销
频繁的创建、销毁线程和线程池,会给系统带来额外的开销。未经池化及统一管理的线程,则会导致系统内线程数上限不可控。
12345678910111213@Overridepublic void renewalTokenIfNecessary(String token) { // 需要异步刷新 Long uid = getValidUid(token); String userTokenKey = getUserTokenKey(uid); Long expireDays = RedisUtils.getExpire(userTokenKey, TimeUnit.DAYS); if (expireDays == -2) { return; } if (expireDays < TOKEN_RENEW_DAYS) {// 小于一天则直接续期 Redi ...
前提提要代码此部分详细代码见Netty实现WebSocket原理
123456789101112131415161718192021222324252627282930313233343536373839404142public void run() throws InterruptedException { // 服务器启动引导对象 ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 128) .option(ChannelOption.SO_KEEPALIVE, true) .handler(new LoggingHandler(LogLevel.INFO)) // 为 bossGroup 添加 日志处理 ...
WebSocket
未读哪怕明天进步一点点,也比原地踏步或退步要好
前置提要Netty WebSocket Server代码
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475@Slf4j@Configurationpublic class NettyWebSocketServer { // 开启netty服务端口8090 public static final int WEB_SOCKET_PORT = 8090; // 创建线程池执行器 private EventLoopGroup bossGroup = new NioEventLoopGroup(1); private EventLoopGroup workerGroup = new NioEventLoopGroup(NettyRuntime.availableProcessor ...