Spring Boot 2.0 版的开源项目云收藏来了!
给大家聊一聊云收藏从 Spring Boot 1.0 升级到 2.0 所踩的坑
先给大家晒一下云收藏的几个数据,作为一个 Spring Boot 的开源项目(https://github.com/cloudfavorites/favorites-web)目前在 Github 上面已经有1600多个 Star,如果按照 SpringBoot 标签进行筛选的话也可以排到第五位。
当云收藏1.0开发完成之后,同步将云收藏部署到了服务器上,申请了一个域名www.favorites.ren方便大家使用,到目前为止:网站的注册用户4000多人,共计收藏文章100000多条,在百度上搜索:云收藏,排在第一的就是云收藏的官网。2年多的时间这个数据其实也并不是很耀眼,但是作为一个学习 Spring Boot 的开源软件来讲,已经不错了。
云收藏的部署之路也挺曲折,刚开始的时候部署在我以前公司的服务器上,后来离职的时候在阿里云买了个1核1G的云服务器,因为安装了 Mysql、Redis、还有其它小软件导致服务器非常卡,那段时间访问云收藏的时候需要等待2-3秒才会有响应。
终于有一天自己也不能忍了,花钱把服务器升级到2核2G,访问速度虽有所提升但还是很不理想,那段时间工作很忙也没时间优化。网站的 Bug 也是一片,有时候还会突然中断服务几个小时,流失了一大批用户,甚至有人在 Github 上面留言说:看来微笑哥已经放弃云收藏了,我看了之后只能苦笑。
到了今年 Spring Boot 2.0 发布的时候,我就计划着把云收藏全面升级到2.0,顺便做一些优化让访问速度快一点。但一拖就是2个月,终于在前几个周末抽出了一点时间,将云收藏升级到了 Spring Boot 2.0 同时修复了一批显而易见的 Bug ,使用 Nginx 将静态图片等资源做了代理,当这些工作完全做完的时候,云收藏的访问速度明显得到了提升,大家可以访问www.favorites.ren体验一下。
将云收藏从 Spring Boot 1.0 升级到 2.0 的时候也遇到了一些问题,在修改的过程中记录下来,今天整理一下分享出来,方便后续升级的朋友少踩一些坑。
1、第一个问题:启动类报错
Spring Boot 部署到 Tomcat 中去启动时需要在启动类添加SpringBootServletInitializer,2.0 和 1.0 有区别。
// 1.0
import org.springframework.boot.web.support.SpringBootServletInitializer;
// 2.0
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class UserManageApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(UserManageApplication.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(UserManageApplication.class, args);
}
}
这个问题好解决只需要重新导包就行。
2、日志类报错:Spring Boot 2.0 默认不包含 log4j,建议使用 slf4j 。
import org.apache.log4j.Logger;
protected Logger logger = Logger.getLogger(this.getClass());
改为:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
protected Logger logger = LoggerFactory.getLogger(this.getClass());
这个也比较好改动,就是需要替换的文件比较多。
3、Spring Boot 2.0 去掉了findOne()方法。
以前的findOne()方法其实就是根据传入的 Id 来查找对象,所以在 Spring Boot 2.0 的 Repository 中我们可以添加findById(long id)来替换使用。
例如:
User user=userRepository.findOne(Long id)
改为手动在userRepository手动添加findById(long id)方法,使用时将findOne()调用改为findById(long id)
User user=userRepository.findById(long id)
delete()方法和findOne()类似也被去掉了,可以使用deleteById(Long id)来替换,还有一个不同点是deleteById(Long id)默认实现返回值为void。
Long deleteById(Long id);
改为
//delete 改为 void 类型
void deleteById(Long id);
当然我们还有一种方案可以解决上述的两种变化,就是自定义 Sql,但是没有上述方案简单不建议使用。
@Query("select t from Tag t where t.tagId = :tagId")
Tag getByTagId(@Param("tagId") long tagId);
4、云收藏升级到 2.0 之后,插入数据会报错,错误信息如下:
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [PRIMARY]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
....
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
...
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '299' for key 'PRIMARY'
这个问题稍稍花费了一点时间,报错提示的是主键冲突,跟踪数据库的数据发现并没有主键冲突,最后才发现是 Spring Boot 2.0 需要指定主键的自增策略,这个和 Spring Boot 1.0 有所区别,1.0 会使用默认的策略。
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private long id;
改动也比较简单,需要在所有的主键上面显示的指明自增策略。
5、Thymeleaf 3.0 默认不包含布局模块。
这个问题比较尴尬,当我将 Pom 包升级到 2.0 之后,访问首页的时候一片空白什么都没有,查看后台也没有任何的报错信息,首先尝试着跟踪了 http 请求,对比了一下也没有发现什么异常,在查询 Thymeleaf 3.0 变化时才发现:Spring Boot 2.0 中spring-boot-starter-thymeleaf 包默认并不包含布局模块,需要使用的时候单独添加,添加布局模块如下:
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
改完之后再访问首页,一切正常,但是回头查看日志信息发现有一个告警信息:
2018-05-10 10:47:00.029 WARN 1536 --- [nio-8080-exec-2] n.n.u.t.decorators.DecoratorProcessor : The layout:decorator/data-layout-decorator processor has been deprecated and will be removed in the next major version of the layout dialect. Please use layout:decorate/data-layout-decorate instead to future-proof your code. See https://github.com/ultraq/thymeleaf-layout-dialect/issues/95 for more information.
2018-05-10 10:47:00.154 WARN 1536 --- [nio-8080-exec-2] n.n.u.t.expressions.ExpressionProcessor : Fragment expression "layout" is being wrapped as a Thymeleaf 3 fragment expression (~{...}) for backwards compatibility purposes. This wrapping will be dropped in the next major version of the expression processor, so please rewrite as a Thymeleaf 3 fragment expression to future-proof your code. See https://github.com/thymeleaf/thymeleaf/issues/451 for more information.
跟踪地址看了一下,大概的意思是以前布局的标签已经过期了,推荐使用新的标签来进行页面布局,解决方式也比较简单,修改以前的布局标签 layout:decorator 为 layout:decorate即可。
6、分页组件PageRequest变化。
在 Spring Boot 2.0 中 ,方法new PageRequest(page, size, sort) 已经过期不再推荐使用,推荐使用以下方式来构建分页信息:
Pageable pageable =PageRequest.of(page, size, Sort.by(Sort.Direction.ASC,"id"));
跟踪了一下源码发现PageRequest.of()方法,内部还是使用的new PageRequest(page, size, sort),只是最新的写法更简洁一些。
public static PageRequest of(int page, int size, Sort sort) {
return new PageRequest(page, size, sort);
}
7、关联查询时候组合返回对象的默认值有变化。
在使用 Spring Boot 1.0 时,使用 Jpa 关联查询时我们会构建一个接口对象来接收结果集,类似如下:
public interface CollectView{
Long getId();
Long getUserId();
String getProfilePicture();
String getTitle();
}
在使用 Spring Boot 1.0 时,如果没有查询到对应的字段会返回空,在 Spring Boot 2.0 中会直接报空指针异常,对结果集的检查会更加严格一些。
8、其它优化
前段时间在学习 Docker ,给云收藏添加了 Docker 、Docker Compose 支持让部署的时候更简单一些;同时修复了一些 bug,对于明显很消耗资源的功能进行了改进,部分功能添加了容错性;本次部署的时候使用了 Nginx 作为反向代理,因为使用了 WebJars 暂时不能使用 Nginx 代理 Js,所以将除过 Js 以外的其它资源都配置了缓存,;数据库由 Mysql 换成了 Mariadb。
以上就是云收藏从 Spring Boot 1.0 到 2.0 所做的一些小改进,做完这些工作之后惊喜的发现云收藏的访问速度比以前快了很多,虽然还有很大的优化空间,但日常使用基本上不会体验到太大的延迟。Spring Boot 2.0 中 Thymeleaf 默认使用了 3.0 ,数据库连接池默认使用了 Hikari ,这两个组件在性能上有很大的提升,同时也是提升云收藏访问速度的因素之一。
未来云收藏还会持续升级,后续会规划一些面向程序员的新功能,敬请期待!
Spring Boot 2.0 版的开源项目云收藏来了!的更多相关文章
- 学习Spring Boot看这两个开源项目就够了!非得值得收藏的资源
Spring Boot我就不做介绍了,大家都懂得它是一个多么值得我们程序员兴奋的框架. 为什么要介绍这两个开源项目呢? 1.提供了丰富的学习实践案例 2.整合了非常多优质的学习资源 不多说了,直接上链 ...
- Spring Boot 2.0(六):使用 Docker 部署 Spring Boot 开源软件云收藏
云收藏项目已经开源2年多了,作为当初刚开始学习 Spring Boot 的练手项目,使用了很多当时很新的技术,现在看来其实很多新技术是没有必要使用的,但做为学习案例来讲确实是一个绝佳的 Spring ...
- Vue+Spring Boot 前后端分离的商城项目开源啦!
新蜂商城 Vue 移动端版本开源啦! 去年开源新蜂商城项目后,就一直在计划这个项目 Vue 版本的改造,2020 年开始开发并且自己私下一直在测试,之前也有文章介绍过测试过程和存在的问题,修改完成后, ...
- spring boot 2.0.0 + shiro + redis实现前后端分离的项目
简介 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码学和会话管理.使用Shiro的易于理解的API,您可以快速.轻松地获得任何应用程序,从最小的移动应用程序到最大 ...
- Spring Boot 2.0系列文章(五):Spring Boot 2.0 项目源码结构预览
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/04/15/springboot2_code/ 项目结构 结构分析: Spring-boot-pr ...
- Spring Boot 2.0(七):Spring Boot 如何解决项目启动时初始化资源
在我们实际工作中,总会遇到这样需求,在项目启动的时候需要做一些初始化的操作,比如初始化线程池,提前加载好加密证书等.今天就给大家介绍一个 Spring Boot 神器,专门帮助大家解决项目启动初始化资 ...
- Spring Boot 2.0正式发布,新特性解读
作者|翟永超 Spring Boot 2.0 来啦,有哪些新特性?升级吗? 写在前面 北京时间 3 月 1 日,经过漫长的等待之后,Spring Boot 2.0 正式发布.作为 Spring 生态中 ...
- spring boot 2.0.3+spring cloud (Finchley)7、服务链路追踪Spring Cloud Sleuth
参考:Spring Cloud(十二):分布式链路跟踪 Sleuth 与 Zipkin[Finchley 版] Spring Cloud Sleuth 是Spring Cloud的一个组件,主要功能是 ...
- Spring 社区的唯一一个国产开源项目 - Spring Cloud Alibaba 毕业了
阿里妹导读:一年多前,Java 界最近发生了一件大事,阿里开源 Spring Cloud Alibaba,并推出首个预览版.Spring Cloud 本身是一套微服务规范,并不是一个拿来即可用的框架, ...
随机推荐
- (网页)12种不宜使用的Javascript语法(转)
转自阮一峰: 最近写的一些小东西,总是出各种各样的问题,用了angular.js反应居然比我的jQuery还慢,客户吐槽了,我又把一个小操作,改成了jQuery.浏览一下大神的的博客.转载一点东西: ...
- 洗礼灵魂,修炼python(49)--巩固篇—包
包(Package) 这个其实前面也说过的,不过同模块一样,没有具体的解析 1.什么是包 在创建许许多多模块后,我们可能希望将某些功能相近的文件组织在同一文件夹下,那么此文件夹(目录)即为包,文件夹( ...
- 洗礼灵魂,修炼python(29)--装饰器(1)—>利用经典案例解析装饰器概念
前提必备 不急着进入正题,在前面函数作用域那一章介绍了闭包,全局变量局部变量,这里再看几个简单的闭包案例: 1):不带参数 注意: 1.这里的name属性是每个函数都有的,可以反馈函数名 2.temp ...
- 洗礼灵魂,修炼python(18)--温故加知新
类型转换: 1.str(),repr(),format():将非字符串数据转换为字符串 str():对象序列化的结果,相当于print输出 repr():程序中某个对象精确值 format():利用特 ...
- 通过日志过滤的方法,统计每天内容详情页面的PV数
1.目的: 每天凌晨0点1分统计用户点击进入内容详情页的次数,对内容点击量形成榜单. 2.分析: A./data/log/epg.access.log日志实时打印用户访问页面的日志,并且每天凌晨0点会 ...
- 简单整理关于C#和Java的区别
相信每个程序猿都有自己最喜欢的编程语言,然而对于编程语言似乎形成一条独特的鄙视链,就如Java和C#常常两边的开发者都是相互鄙视,然后他们一起共同鄙视全世界最好的编程语言——PHP 哈哈,但是其实我想 ...
- SQL Server自动备份存储过程和视图的方法
1 建立备份数据表 CREATE TABLE [dbo].[ProcBackup]( ,) NOT NULL, [name] [sysname] NOT NULL, ) NULL, [obj_id] ...
- Python scikit-learn (metrics): difference between r2_score and explained_variance_score?
I noticed that that 'r2_score' and 'explained_variance_score' are both build-in sklearn.metrics meth ...
- Flume-1.8.0_部署与常用案例
该文章是基于 Hadoop2.7.6_01_部署 进行的 Flume官方文档:FlumeUserGuide 常见问题:记flume部署过程中遇到的问题以及解决方法(持续更新) 1. 前言 在一个完整的 ...
- Django admin 的模仿流程