Spring思維導圖,讓Spring不再難懂(cache篇)

關於緩存

緩存是實際工作中非常常用的一種提高性能的方法。而在java中,所謂緩存,就是將程序或系統經常要調用的對象存在內存中,再次調用時可以快速從內存中獲取對象,不必再去創建新的重複的實例。這樣做可以減少系統開銷,提高系統效率。

在增刪改查中,數據庫查詢佔據了數據庫操作的80%以上,而非常頻繁的磁盤I/O讀取操作,會導致數據庫性能極度低下。而數據庫的重要性就不言而喻了:

  • 數據庫通常是企業應用系統最核心的部分
  • 數據庫保存的數據量通常非常龐大
  • 數據庫查詢操作通常很頻繁,有時還很複雜

在系統架構的不同層級之間,為了加快訪問速度,都可以存在緩存

Spring思維導圖,讓Spring不再難懂(cache篇)

spring cache特性與缺憾

現在市場上主流的緩存框架有ehcache、redis、memcached。spring cache可以通過簡單的配置就可以搭配使用起來。其中使用註解方式是最簡單的。

Spring思維導圖,讓Spring不再難懂(cache篇)

Cache註解

Spring思維導圖,讓Spring不再難懂(cache篇)

從以上的註解中可以看出,雖然使用註解的確方便,但是缺少靈活的緩存策略,

緩存策略:

  • TTL(Time To Live ) 存活期,即從緩存中創建時間點開始直到它到期的一個時間段(不管在這個時間段內有沒有訪問都將過期)
  • TTI(Time To Idle) 空閒期,即一個數據多久沒被訪問將從緩存中移除的時間

項目中可能有很多緩存的TTL不相同,這時候就需要編碼式使用編寫緩存。

條件緩存

根據運行流程,如下@Cacheable將在執行方法之前( #result還拿不到返回值)判斷condition,如果返回true,則查緩存;

<code>@Cacheable(value="user",key="#id",condition="#idlt10")
publicUserconditionFindById(finalLongid)
/<code>

如下@CachePut將在執行完方法後(#result就能拿到返回值了)判斷condition,如果返回true,則放入緩存

<code>@CachePut(value="user",key="#id",condition="#result.usernamene'zhang'")
publicUserconditionSave(finalUseruser)
/<code>

如下@CachePut將在執行完方法後(#result就能拿到返回值了)判斷unless,如果返回false,則放入緩存;(即跟condition相反)

<code>@CachePut(value="user",key="#user.id",unless="#result.usernameeq'zhang'")
publicUserconditionSave2(finalUseruser)
/<code>

如下@CacheEvict, beforeInvocation=false表示在方法執行之後調用(#result能拿到返回值了);且判斷condition,如果返回true,則移除緩存;

<code>@CacheEvict(value="user",key="#user.id",beforeInvocation=false,condition="#result.usernamene'zhang'")
publicUserconditionDelete(finalUseruser)

/<code>
  • 小試牛刀,綜合運用:
<code>    @CachePut(value = "user", key = "#user.id")
public User save(User user) {
users.add(user);
return user;
}

@CachePut(value = "user", key = "#user.id")
public User update(User user) {
users.remove(user);
users.add(user);
return user;
}

@CacheEvict(value = "user", key = "#user.id")
public User delete(User user) {
users.remove(user);
return user;
}

@CacheEvict(value = "user", allEntries = true)
public void deleteAll() {
users.clear();
}

@Cacheable(value = "user", key = "#id")
public User findById(final Long id) {
System.out.println("cache miss, invoke find by id, id:" + id);
for (User user : users) {
if (user.getId().equals(id)) {
return user;
}
}
return null;
}
/<code>

配置ehcache與redis

  • spring cache集成ehcache,spring-ehcache.xml主要內容:
<code><dependency>
\t<groupid>net.sf.ehcache/<groupid>
\t<artifactid>ehcache-core/<artifactid>
\t<version>${ehcache.version}/<version>
/<dependency>
/<code>
<code>


<bean>
<property>
/<bean>

<bean>
<property>
<property>
/<bean>


<annotation-driven>
/<code>
  • spring cache集成redis,spring-redis.xml主要內容:
<code><dependency>
\t<groupid>org.springframework.data/<groupid>
\t<artifactid>spring-data-redis/<artifactid>
\t<version>1.8.1.RELEASE/<version>
/<dependency>
<dependency>
\t<groupid>org.apache.commons/<groupid>
\t<artifactid>commons-pool2/<artifactid>
\t<version>2.4.2/<version>
/<dependency>
<dependency>
\t<groupid>redis.clients/<groupid>
\t<artifactid>jedis/<artifactid>
\t<version>2.9.0/<version>
/<dependency>
/<code>
<code>
<description>redis配置/<description>

<bean>
\t<property>
\t<property>
\t<property>
\t<property>
\t<property>
/<bean>


<bean>
\t<property>
\t<property>
\t<property>
/<bean>

<bean>\t p:connectionFactory-ref="jedisConnectionFactory">
\t<property>
\t\t<bean>
\t/<property>
\t<property>
\t\t<bean>
\t/<property>
\t<property>
\t\t<bean>
\t/<property>
\t<property>
\t\t<bean>
\t/<property>
/<bean>


<bean>\t c:redisOperations-ref="redisTemplate">
\t
\t<property>
\t<property>
\t
\t<property>
\t\t

\t\t\t<entry>
\t\t\t<entry>
\t\t\t<entry>
\t\t\t
\t\t\t<entry>
\t\t\t<entry>
\t\t\t<entry>
\t\t

\t/<property>
/<bean>

<annotation-driven>

/<code>

項目中註解緩存只能配置一個,所以可以通過以下引入哪個配置文件來決定使用哪個緩存。

<code><import>

/<code>

當然,可以通過其他配置搭配使用兩個緩存機制。比如ecache做一級緩存,redis做二級緩存。

Spring思維導圖,讓Spring不再難懂(cache篇)

更加詳細的使用與配置,可以參考項目中spring-shiro-training中有關spring cache的配置。

  • https://git.oschina.net/wangzhixuan/spring-shiro-training.git

寫在最後,希望對在java開發路上的你,有些幫助!

碼農三哥,一名普通程序員,會點java軟件開發,對AI人工智能有點興趣,後續會每日分享些關於互聯網技術方面的文章,感興趣的朋友可以關注我,一起交流學習。

想轉型或剛步入程序員Java開發的朋友,有問題可以留言或私信我。

再次感謝你的閱讀!


分享到:


相關文章: