spring 系框架如 spring,springboot,springcloud 等已成为 java 开发的标配,笔者也是 spring 系框架的多年用户,它们遵循统一的原则,原理清晰,实现优雅, 更新及时,很多最佳实践慢慢都沉淀为规则,为广大 javaer 提供了很多开箱即用的便利,大大降低开发成本。
官方网站一般是学习和查阅某种技术资料的首选, spring 也不例外. 前段时间,我惊喜的发现它们的官方网站 改版了, 风格更加清爽轻量,访问速度更快,布局更加条理找文档更加方便了。在这个前端框架层出不穷的年代,我有点好奇 spring 的官网前端和后端分别是用 啥做的, 又有啥亮点呢? 我们来一探究竟。
分析网站技术架构有一个不错的工具 wappalyzer, 不过我们这里用不到,因为他家官网源码是开源的。 把源码 clone 下来,README 上面一开始就写着:
In addition to the practical purpose of powering Spring's home on the web, this project is designed to serve as a reference application-- resource that developers can use to see how the Spring team have used Spring to implement a real-world app with a few interesting requirements. We hope you'll find it useful!
有趣,这个项目是官方推荐的学习项目,开发者可以把这个项目作为一个参考项目,从这个项目学到 spring 团队怎么用 spring 来实现一个真实项目的。 生产环境即 spring 官网,需求明确,不算复杂也不会太简单,官方实现肯定代码质量也有保证,用来学习非常好。
--sagan
|-- sagan-client
|-- sagan-renderer
|-- sagan-site
这是一个 gradle 多模块项目, 项目按功能划分到 3 个子模块。这是一个很好的实践,将项目代码按功能分成多个子模块。
这是前端模块,该模块使用 node.js and npm 和 Webpack 进行编译, 包含所有 web 端的资源:
这个模块有 2 个有趣的点,我可以学习这种前后端分离的方式:
这是渲染模块,简约而不简单,作用是将 markdown asciidoc 等文档渲染成 html 。 这里我们看到了 springboot 一些经典的用法, 如
配置自动注入 ,yaml 中的配置可以自动注入到需要的类中,如 RendererProperties
spring-boot-starter-hateoas
HATEOAS 即 hypertext as the engine of application state, 超媒体即应用状态引擎,它是 Richardson 提出的 REST 成熟的模型中的第 4 层也就是最高一层。
它要求资源不但有链接信息, 还应该有可以执行的动作信息,这样客户端就可以动态发现所有它能执行的动作。
spring-boot-starter-hateoas 就是 HATEOAS 的一个实现, 该仓库有几处用了它,如 GuideResource
。
远程调用
非微服务架构,也可以方便的使用远程调用,见 GithubClient
. 在这里可以学到另一个很有用的方法-使用 springboot 短短几行代码下载 git 仓库:
/**
* Download a repository as a zipball
* @param organization the github organization name
* @param repository the repository name
* @return the zipball as raw bytes
*/
public byte[] downloadRepositoryAsZipball(String organization, String repository) {
try {
byte[] response = this.restTemplate.getForObject(REPO_ZIPBALL_PATH,
byte[].class, organization, repository);
return response;
}
catch (HttpClientErrorException ex) {
throw new GithubResourceNotFoundException(organization, ex);
}
}
这是核心模块,它获获取内容,渲染成 html,展示给前端。
我们首先来看看它是怎么和 sagan-client
关联起来的。其实比较简单,将静态资源路径添加到 springboot 配置文件即可,如下:
spring:
profiles: standalone
resources:
static_locations:
- file:${client.dir}/build/dist/
devtools:
restart:
additional_paths:
- ../sagan-client/build/dist/
additional_exclude: "**/*.js,**/*.css"
然后它是怎么使用 sagan-client
服务的呢, 见 SaganRendererClient
。此外可见项目并不是国内流行的 mybatis 而是 jpa, 经过 springboot-data-jpa 的加持,有很强的灵活性和可读性。再我的下一个项目,我可能也会试试 jpa 。
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
Page<Post> findByCategoryAndDraftFalse(PostCategory category, Pageable pageable);
Page<Post> findByDraftTrue(Pageable pageRequest);
@Query("select p from Post p where YEAR(p.publishAt) = ?1 and MONTH(p.publishAt) = ?2 and DAY(p.publishAt) = ?3")
Page<Post> findByDate(int year, int month, int day, Pageable pageRequest);
}
最后,sagan-renderer 是一个常规的 mvc 项目,视图层使用 thymeleaf, 将结果返回给浏览器。这样,整个流程就完成了。
最后,我们来总结一下,这个项目可以学到什么.
感谢您的阅读,欢迎访问TOP 开发者社区沟通交流。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.