說在前邊
最近部門幾位同僚受了一些委屈相繼離職,共事三年臨别之際頗有不舍,待一切手續辦妥帖,寒暄過後送他們出公司,幾個老哥臨别時沖我鬼魅一笑,我頓時心裡一緊有種不好的預感,這事絕對沒有這麼簡單。等我接手這幾個大佬的項目後,應驗了我的預感,此刻我居然有點後悔,為啥送别之時沒揍他們一頓!哈哈哈~ 而這種打人的沖動,在我開始優化幾位老哥的項目時候,變得越來越強烈。

有個坑
技術部每個月都會組織一下代碼走查及優化,以前是各自審查優化自己的項目,如今幾位老哥的離職他們的項目就落到了我的頭上。對于程式員來說最痛苦的事情就是接手别人的項目,還要做優化改造,因為這一點也不比重構一遍項目簡單。不過,軍令在前,沒辦法硬着頭皮上吧!
第一個優化的點就讓我有點崩潰,這幾個大佬的技能能力很強,一直都是我學習的榜樣,但在項目裡幾乎所有的日期格式化都這樣用
SimpleDateFormat
,像如下代碼這樣實作,emm~ ,受過傷的男人怎麼啥事都做的出來,哈哈哈~
SvcOrderDailyStatisticsPo orderDailyStatisticsPo = new SvcOrderDailyStatisticsPo();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date stationTime = dateFormat.parse(dateFormat.format(svcWorkOrderPo.getPayEndTime()));
orderDailyStatisticsPo.setStatisticalDate(stationTime);
而且項目中的時間和日期API用的也比較混亂,考慮到
java.util.Date
和
java.util.Calendar
不支援時區,且非線程安全,對于日期的計算相對繁瑣,技術部一緻要求用JDK1.8以後的
java.time
LocalDateTime
。但不少人還是在用
java.util.Date
java.util.Calendar
處理日期。
優化方案
時間格式化是使用頻率非常高的,如何讓時間格式化變得既簡單又不用重複造輪子,那麼就應将它抽象出來,作為全局的日期格式化處理,下面就結合實踐簡單介紹下幾種優化方案。
測試位址:
http://127.0.0.1:8080/timeTest
@GetMapping("/timeTest")
public OrderInfo timeTest() {
OrderInfo order = new OrderInfo();
order.setCreateTime(LocalDateTime.now());
order.setUpdateTime(new Date());
return order;
}
1、@JsonFormat注解
使用
@JsonFormat
注解格式化時間,應該算是一個基本操作了,大部分開發者都應用此種方式,簡單友善。
/**
* @Author: xiaofu
* @Description:
*/
public class OrderInfo {
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
測試一下結果,發現
Date
類型和
LocalDateTime
類型都格式化成功,但還是有個問題,這樣做仍然比較繁瑣,每個實體類的日期字段都要加
@JsonFormat
注解,重複的工作量也不小。接着往下看~
2、全局配置 (1)
Springboot
已經為我們提供了日期格式化
${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}
,這裡我們需要進行全局配置,配置比較簡單,也無需在實體類屬性上添加
@JsonFormat
注解。
/**
* @Author: xiaofu
* @Description:
*/
public class OrderInfo {
//@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
//@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
隻需要用
@Configuration
定義一個配置類,注入兩個
Bean
即可完成全局日期格式化處理,這種方式也是目前我項目中正在用的方式。
/**
* @Author: xiaofu
* @Description:
*/
@Configuration
public class LocalDateTimeSerializerConfig {
@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
private String pattern;
@Bean
public LocalDateTimeSerializer localDateTimeDeserializer() {
return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
}
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer());
}
}
這種方式可支援
Date
LocalDateTime
類型并存,那麼有一個問題就是現在全局時間格式是
yyyy-MM-dd HH:mm:ss
,但有的字段卻需要
yyyy-MM-dd
格式咋整?
那就需要配合
@JsonFormat
注解使用,在特定的字段屬性添加
@JsonFormat
注解即可,因為
@JsonFormat
注解優先級比較高,會以
@JsonFormat
注解标注的時間格式為主。
3、全局配置 (2)
這種全局配置的實作方式與上邊的效果是一樣的,不過,要注意的是使用這種配置後,字段手動配置
@JsonFormat
注解将不再生效。
/**
* @Author: xiaofu
* @Description:
*/
public class OrderInfo {
//@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
//@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
/**
* @Author: xiaofu
* @Description:
*/
@Configuration
public class LocalDateTimeSerializerConfig {
@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
private String pattern;
@Bean
@Primary
public ObjectMapper serializingObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
@Override
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(value.format(ofPattern(pattern)));
}
}
public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext) throws IOException {
return LocalDateTime.parse(p.getValueAsString(), ofPattern(pattern));
}
}
}
總結
分享了一個
Springboot
項目開發過程中的一個小技巧,也順便吐槽一下項目優化中遇到的坑,優化别的人的代碼雖然是一件比較痛苦的事情,但在這個過程中确實能學習到很多技巧,對個人的技能提升也是很有幫助,因為都是些能夠實實在在提高開發效率的幹貨。
小福利:
擷取到一些極客課程 ,噓~,免費 送給小夥伴們。關注公号回【極客】自行領取