[译] SpringFramework 概述

概述

Spring 使得创建 Java 企业级应用更加容易。它提供了你在企业环境下拥抱 Java 语言所需要的一切,支持 JVM 平台上的 Groovy 和 Kotlin 作为备选语言,并且提供了根据应用程序的需求创建多种架构的灵活性。从 SpringFramework 6.0 开始,Spring 需要 Java 17 以上的版本。

Spring 支持广泛的应用场景。在一个大型企业里,应用程序经常会存在很长时间,并且必须运行在一个开发者不能控制升级周期的 JDK 和应用服务器上。 另外一些可能会作为一个内嵌服务器的单独 jar 包,运行在一个云环境里,还有一些可能是一个不需要服务器的独立应用程序(例如批处理或者集成处理工作)。

Spring 是开源的。它有一个庞大而活跃的社群,基于各种实际用例,提供持续反馈。这也帮助了 Spring 在相当长一段时间内成功发展。。

当我们在谈 Spring 时我们在谈什么

“Spring” 这个术语在不同的语境下有着不同的含义。它可以用来表示 SpringFramework 这个项目自身,一切都是从这里开始的(-译者按:梦开始的地方)。随着时间的推移,又构建了一些以 SpringFramework 为基础的 Spring 项目。大部分情况下,当人们谈论 Spring,他们的意思是 Spring 整个系列(-译者按:俗称全家桶)。本参考文档只针对这个基础进行介绍:SpringFramework 本身。

SpringFramework 被分成不同的模块。应用程序可以根据他们所需要的模块进行选择。这些模块中处于核心的是 core container,包括配置模型和依赖注入机制。除此之外,SpringFramework 还对于不同应用架构提供基础支持,包括消息传递、事务以及持久化和 web。它同时也包含了基于 Servlet 的 SpringMVC web 框架以及Spring WebFlux 响应式web框架。

关于这些模块需要注意的是:

Spring 的框架,允许部署到 JDK 9 的模块路径(“Jigsaw”)。对于在支持 “Jigsaw” 的应用程序中的使用,Spring Framework 5 的 jar 包里面,携带了 “Automatic-Module-Name” 的 manifest entries,它定义了稳定的语言级别模块名(例如:“spring.core”,“spring.context” 等等),它与 jar 的 artifact 名字独立( 这些 jar 遵循同样的模式,例如 “spring-core” 和 “spring-context”。 “-” 代替 “.”

聊点什么

谈心的文章好久没有写了,初秋的夜晚,键盘的敲击声格外响亮,一时竟然不知道从哪儿说起。我从今年开始,格外的怀旧起来。不只是怀念那个青春的八十年代,质朴的九十年代,而且竟然怀念起仿佛刚刚过去的两千年。也许是现在回看,带着滤镜和光影的原因吧。但我着实相信,过去确实比现在更加美丽一些。试问,现在还有什么歌曲能像过去的八九十年代扣人心弦,还有谁能写出像罗大佑那样充满人文情怀的歌词?我不是一个保守的人,现在的歌曲我也会经常听,但摇滚光是呐喊、嘶吼没有反思,民谣只有情绪没有韵味,流行歌曲更是惨不忍听。现在一首歌有四句比较朗朗上口一些,就能风靡一时,然后人们快速遗忘,寻找下一个。人们没法不遗忘,因为实在没有什么好怀念的。

人们在路上疯狂且快速的奔跑着,前面有人但凡有一点点挡道,便会怒从心头起。也许在快速奔跑中,人们才来不及为过去伤怀,风驰电掣,麻木一生。

如果我也这样,多好!

可是,我偏偏要将步伐放慢,歪着头想想,于是总感觉自己是个慢半拍的人。

今年一整年,几乎没有在公众号上发表任何文章,我想找个没人的地方,倾吐一下自己的想法。

失落与大门

今年是让我特别失落的一年,特别失落。

还有几年,就到传说中的中年危机了。坦白说,我直到今年才有些许明白,中年危机的真实含义。

所谓中年危机,并不单单是一个经济的问题,而是方方面面。

这个尴尬的年纪,朋友帮不上你,于是友情危机;妻子不理解你,于是婚姻危机;父母埋怨你,于是亲情危机。各方面的危机,想汹涌的几股暗流,汇集而来,向涉世未深的你迎面击来。

这个年纪,看似血气方刚,实则是最脆弱的年纪,没有经验的积淀,没有人脉的积淀,只有你自己硬抗,像不喝药,凭借自己的身体素质对抗一场重感冒。

扛过去,就会好很多。后面遇到再多糟心事,有了前面的抗体,总是会好过一些。

呵,男人四十!

今年的夏天格外热,但是在每次下班骑车回家的路上,听着歌,经常感觉浑身一阵冷战。也许是突然被某句歌词所触动,伤怀往事、怀疑信念。

于是有一阵子,我囤了很多书。最明显的变化是,我开始看外国小说了,以前硬着头皮两次入门、两次放弃的《安娜卡列尼娜》,这次竟然能够看的津津有味,甚至有时候,会有冲动,买下托尔斯泰的《战争与和平》这部据说很冗长的巨著一看。

年龄大了,学会妥协了。年少时,看那些翻译过来的腔调,就是不喜欢看不下去,我从来不理解为什么要冗长的心理描写,为什么人物的每一句台词,中间都要被“xxx说”拦腰斩为两截,如此种种。

今年突然明白了,这就是文化差异,不同地区的表达习惯,是会有不同的,不只是语汇的区分。我们应该注重的是书里面的所蕴含的光辉思想以及作者倾注的满腔热情。我们在《史记-项羽本纪》里面看不到一句项羽的心理描写,仅凭几句念白,几句描写,一个英雄就这样被人千年。

所以,中国会有山水画,笔墨留白,却依然已经满怀,而西方的工笔画、油画也依然是情绪饱满的。

留白也有水货,浓墨重彩也有精品。

这么想着,一道艺术的大门就这样为我敞开。

思想越包容,视野越广阔。有些时候,就是需要换一个视角和思维的转变。

AI 与艺术

AI 是今年的热词,仿佛一夜之间,什么都可以用 AI 做了。

就在这孤独的一年,我的阅读量和艺术视角,刻意地伸长,触及到了我之前出于懒惰不会触及的地方。就凭我简单的探索,我就知道 AI 根本没戏,虽然,我是一个技术人,但是我从来不认为 AI 能够写出那些不朽的作品,能够勾勒出那些美妙的线条。

很简单,因为 AI 不是人,没有意识和灵魂。

不是人,所以不会像人一样犯错,与此同时,也缺少了很多偶然。须知,很多艺术就是来源于偶然的灵光一现。

当然,还有一个重要的因素,就是伟大的读者催生伟大的作品,我们很难想象,被 AI 和短视频喂饱的读者们会有什么眼光去苛求那些内容的生产者。

想来也荒唐,到底是谁训练了谁?

将来的市场,AI 肯定是能挤掉一部分人的作品的。那些平庸的、毫无新意和灵魂的作品,会被 AI 取而代之。这或许倒是一个良币驱逐劣币的过程。

试看当今的歌坛,有多惨不忍睹就知道,科技能帮助人在艺术道路上走一段路,可是,剩下的路还是要靠人类自己走。

这是人类的宿命。

AI 也没有用。

也许,将来 AI 可能会突然大爆发,像人一样有了意识,但也是需要和人一样有痛苦的经历的。这样,AI 既有了人的意识,又有了人的经历和痛苦,那就是人类无疑了。

也许是 AI 被我们人类同化了吧?不知道是否可以当成人类的一场惨胜。

人文与科技

自己今年的时间,比往年多了一些,想做的事情太多,结果现在一件事也没有做成。自己不甘于只做一个消费者,也想做一个内容的生产者。

但生成什么内容,却让自己又一次开始了犹豫和纠结。

也许,这也是我的宿命,我注定会饿死在人文与科技的十字路口。

人文类的内容,是我的兴趣所在,但是目前的境况很是不尽人意,言论管控空前,万马齐喑。再加上饭圈文化和粉丝量的有限和题材内容的饱和,很难找到一个切入口完成一些看似“伟大”的事情。

科技类的内容,也是我想做的,看起来比人文的圈子要简单一些,但是,也比较枯燥一些,而且,自己驾驭起来,并不如人文类的容易一些,粉丝量的成长幅度,肯定比不上人文类的 up 主,毕竟大家都想在下班后,躺在床上,听听历史的八卦,谁会主动坐在桌前,听你分享一些你自己以为讲的很明白的原理和架构?

但是,自己毕竟是吃技术这碗饭的,而且自己在今年换工作之后,看到身边有的人无知的像一头猪一样,不禁觉得可笑之余,转念一想,自己是否在另一些人的眼里,也无知得可笑呢?于是,我立志,要把自己的技术短板填补上,尽量不看起来像一头猪。

综合起来,貌似技术up这条路,自己会走得更踏实一些,而且人文类的内容,要想做得出彩,关键在于自己阅历的积淀和对世情的理解。同样是看《潜伏》,有的人能分析地头头是道,非经一番历练之人,不可懂其中深味也。

希望与失望

当蜘蛛网无情地查封了我的炉台,

当灰烬的余烟叹息着贫困的悲哀,

我依然固执地铺平失望的灰烬,

用美丽的雪花写下:相信未来。

《红楼梦》碎碎念

个人读《红楼梦》之所感所思,想到哪儿,写到哪儿,不拘章法,也无体系,不求闻达,但求深思。

Telegram bot 入门实践

什么是 Bot

Bot 的概念在官网的介绍稍微有点繁琐和,详细可以了解官网介绍

简单来说,bot 就是你在 telegram 中的一个特殊账号,你申请了 bot,这个 bot 就是你的代理人,你发号施令到 bot,bot 会响应你的指令,仅此而已。

申请 bot 需要找 BotFather(名字起的很形象),具体过程官网说的比较详细,此处不赘言。但是需要强调的一点是,bot 仅仅是你的代理人而已,真正执行你指令的是你自己部署的脚本,如果你不部署自己的脚本,在 bot 中输入指令,是没有任何响应的。

你、bot和你部署的脚本关系如下:

https://raw.githubusercontent.com/anriclee/diagramStorage/master/telegram.drawio.png

脚本

上面说过了,bot 只是你在 telegram 的一个代理,真正干活的是你的脚本。既然自己写脚本,就会存在两个问题:接受指令、做出响应。

接受指令

对于如何让脚本接受指令,官方提供了两种思路:推模式 、拉模式。

  • 拉模式

这种模式,官方不太推荐。简单而言,就是自己部署一个脚本,不断执行 get 请求,获取自己 bot 的更新信息,就好比一个仆人一直在问你:

有没有需要我做的?

有没有需要我做的?

有没有需要我做的?

询问的方式也比较简单:

curl -X GET https://api.telegram.org/bot[token]/getUpdates

这里的 token,就是上面申请 bot 完毕后,得到的 token, 出于脱敏,我使用 [token] 代替,下同。这种方法比较笨拙,轮询的频次太高和太低都不行,而且你在 bot 中发布一条指令后,可能并不能够马上得到执行,会有延迟。

基于 PostgreSQL 的群聊搜索实践

背景

2021年年初,探探上线了群聊功能,并且支持按照群名进行模糊搜索。

对于复杂场景的搜索,业界一般使用非常流行的 ElasticSearch。由于我们的群数据较少,截止到目前还没有达到千万级的量级,且搜索场景比较简单,而 PostgreSQL 对全文搜索又支持得比较好,所以选择了 PostgreSQL 来实现群搜索需求。 在使用 PostgreSQL 做群搜索的过程中,也经历了由简单到复杂的迭代过程,中间也踩了不少坑。 下面的几个例子说明了方案的演进过程和我们的优化思路,希望能够对大家有所帮助。

LIKE 模糊查询

提到模糊搜索,最简单的办法就是对搜索列进行 like 匹配: 在输入词的前后加上 % 即可,如下所示:

SELECT * FROM groups WHERE name LIKE '%探探%';

这种方案可行是可行了,但是实现过于简单粗暴。对此方案进行测试:

建一张简单的表进行测试,表结构如下:

lixuehan=# \d groups;
                                   Table "public.groups"
 Column |         Type          | Collation | Nullable |              Default
--------+-----------------------+-----------+----------+------------------------------------
 id     | bigint                |           | not null | nextval('groups_id_seq'::regclass)
 name   | character varying(50) |           |          |
Indexes:
    "groups_pkey" PRIMARY KEY, btree (id)

表中只有两列:主键 id 以及群名 name