日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Spring Cache抽象-使用Java类注解的方式整合EhCache

發(fā)布時(shí)間:2025/3/21 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Cache抽象-使用Java类注解的方式整合EhCache 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  • 概述
  • 工程結(jié)構(gòu)
  • 源碼

概述

Spring Cache抽象-之緩存注解這篇博文中我們介紹了SpringCache抽象注解的使用方式

既然這是一個(gè)抽象,我們需要一個(gè)具體的緩存存儲實(shí)現(xiàn)。比價(jià)流行的有:基于JDK java.util.concurrent.ConcurrentMap的緩存,EhCache,Gemfire緩存,Caffeine,Guava緩存和兼容JSR-107的緩存等等。這里我們使用Ehcache來實(shí)現(xiàn)這個(gè)緩存。

同時(shí),我們使用EhCacheManagerFactoryBean的configLocation屬性指定Ehcache的設(shè)置。如果未明確指定,則默認(rèn)為ehcache.xml。


工程結(jié)構(gòu)

以及EhCache的配置文件:

pom.xml 關(guān)鍵的依賴

<properties> <springframework.version>4.3.9.RELEASE</springframework.version><ehcache.version>2.10.4</ehcache.version> </properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${springframework.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${springframework.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${springframework.version}</version></dependency><!-- EHCache --><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId><version>${ehcache.version}</version></dependency><!-- SLF4J/Logback --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.1.7</version></dependency> </dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.2</version><configuration><source>1.7</source><target>1.7</target></configuration></plugin></plugins></build> </project>

ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"monitoring="autodetect" dynamicConfig="true"><diskStore path="java.io.tmpdir" /><cache name="products" maxEntriesLocalHeap="100"maxEntriesLocalDisk="1000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600"memoryStoreEvictionPolicy="LFU" transactionalMode="off"><persistence strategy="localTempSwap" /></cache> </ehcache>
  • 我們設(shè)置一個(gè)名為’products’的緩存。

  • 最多100個(gè)products將保存在內(nèi)存[堆疊]存儲中,

  • 最多1000個(gè)products將被保留在DiskStore中

  • 指定的路徑為“java.io.tmpdir”,它指的是默認(rèn)的臨時(shí)文件路徑。

  • 如果product閑置超過5分鐘,壽命超過10分鐘,products緩存將會過期


實(shí)體類

package com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain;import java.io.Serializable;public class Product implements Serializable {private static final long serialVersionUID = 123L;private String name;private double price;/*** * * @Title:Product* * @Description:構(gòu)造函數(shù)* * @param name* @param price*/public Product(String name, double price) {this.name = name;this.price = price;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}}

Product接口

package com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.service;import com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product;public interface ProductService {Product getByName(String name);Product updateProduct(Product product);void refreshAllProducts(); }

接口實(shí)現(xiàn)類 及緩存配置

package com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.service;import java.util.ArrayList; import java.util.List;import org.apache.log4j.Logger; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service;import com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product;/*** * * @ClassName: ProductServiceImpl* * @Description:@Service標(biāo)注的服務(wù)層* * @author: Mr.Yang* * @date: 2017年10月3日 下午5:22:30*/@Service("productService") public class ProductServiceImpl implements ProductService {private static final Logger logger = Logger.getLogger(ProductServiceImpl.class);private static List<Product> products;static {products = getDummyProducts();}@Cacheable(cacheNames = "products", key = "#name", condition = "#name != 'HTC'", unless = "#result==null")@Overridepublic Product getByName(String name) {logger.info("<!----------Entering getByName()--------------------->");for (Product product : products) {if (product.getName().equalsIgnoreCase(name)) {return product;}}return null;}@CachePut(cacheNames = "products", key = "#product.name", unless = "#result==null")@Overridepublic Product updateProduct(Product product) {logger.info("<!----------Entering updateProduct()--------------------->");for (Product p : products) {if (p.getName().equalsIgnoreCase(product.getName())) {p.setPrice(product.getPrice());return p;}}return null;}@CacheEvict(cacheNames = "products", allEntries = true)@Overridepublic void refreshAllProducts() {}private static List<Product> getDummyProducts() {products = new ArrayList<Product>();products.add(new Product("IPhone", 500));products.add(new Product("Samsung", 600));products.add(new Product("HTC", 800));return products;}}

關(guān)鍵配置類 ,以及加載enhance

package com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.configuration;import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.ehcache.EhCacheCacheManager; import org.springframework.cache.ehcache.EhCacheManagerFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource;@EnableCaching @Configuration @ComponentScan(basePackages = "com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache") public class AppConfig {@Beanpublic CacheManager cacheManager() {return new EhCacheCacheManager(ehCacheCacheManager().getObject());}@Beanpublic EhCacheManagerFactoryBean ehCacheCacheManager() {EhCacheManagerFactoryBean factory = new EhCacheManagerFactoryBean();factory.setConfigLocation(new ClassPathResource("ehcache/ehcache.xml"));factory.setShared(true);return factory;} }

單元測試

package com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache;import org.apache.log4j.Logger; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.AbstractApplicationContext;import com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.configuration.AppConfig; import com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product; import com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.service.ProductService;public class SpringCacheWithEhCacheTest {private static final Logger logger = Logger.getLogger(SpringCacheWithEhCacheTest.class);AbstractApplicationContext context = null;@Beforepublic void initContext() {context = new AnnotationConfigApplicationContext(AppConfig.class);}@Testpublic void test() {ProductService service = (ProductService) context.getBean("productService");logger.info("IPhone ->" + service.getByName("IPhone"));logger.info("IPhone ->" + service.getByName("IPhone"));logger.info("IPhone ->" + service.getByName("IPhone"));logger.info("HTC ->" + service.getByName("HTC"));logger.info("HTC ->" + service.getByName("HTC"));logger.info("HTC ->" + service.getByName("HTC"));Product product = new Product("IPhone", 550);service.updateProduct(product);logger.info("IPhone ->" + service.getByName("IPhone"));logger.info("IPhone ->" + service.getByName("IPhone"));logger.info("IPhone ->" + service.getByName("IPhone"));logger.info("Refreshing all products");service.refreshAllProducts();logger.info("IPhone [after refresh]->" + service.getByName("IPhone"));logger.info("IPhone [after refresh]->" + service.getByName("IPhone"));logger.info("IPhone [after refresh]->" + service.getByName("IPhone"));}@Afterpublic void releaseContext() {((AbstractApplicationContext) context).close();}}

輸出結(jié)果分析

2017-10-03 20:54:55,026 INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@7bd1a567: startup date [Tue Oct 03 20:54:55 BOT 2017]; root of context hierarchy 2017-10-03 20:54:55,858 INFO [main] (EhCacheManagerFactoryBean.java:130) - Initializing EhCache CacheManager 2017-10-03 20:54:56,711 INFO [main] (ProductServiceImpl.java:40) - <!----------Entering getByName()---------------------> 2017-10-03 20:54:56,715 INFO [main] (SpringCacheWithEhCacheTest.java:32) - IPhone ->com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product@1a8f392 2017-10-03 20:54:56,716 INFO [main] (SpringCacheWithEhCacheTest.java:33) - IPhone ->com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product@1a8f392 2017-10-03 20:54:56,716 INFO [main] (SpringCacheWithEhCacheTest.java:34) - IPhone ->com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product@1a8f392 2017-10-03 20:54:56,717 INFO [main] (ProductServiceImpl.java:40) - <!----------Entering getByName()---------------------> 2017-10-03 20:54:56,717 INFO [main] (SpringCacheWithEhCacheTest.java:36) - HTC ->com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product@68c06cac 2017-10-03 20:54:56,717 INFO [main] (ProductServiceImpl.java:40) - <!----------Entering getByName()---------------------> 2017-10-03 20:54:56,717 INFO [main] (SpringCacheWithEhCacheTest.java:37) - HTC ->com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product@68c06cac 2017-10-03 20:54:56,718 INFO [main] (ProductServiceImpl.java:40) - <!----------Entering getByName()---------------------> 2017-10-03 20:54:56,718 INFO [main] (SpringCacheWithEhCacheTest.java:38) - HTC ->com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product@68c06cac 2017-10-03 20:54:56,724 INFO [main] (ProductServiceImpl.java:52) - <!----------Entering updateProduct()---------------------> 2017-10-03 20:54:56,734 INFO [main] (SpringCacheWithEhCacheTest.java:43) - IPhone ->com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product@1a8f392 2017-10-03 20:54:56,735 INFO [main] (SpringCacheWithEhCacheTest.java:44) - IPhone ->com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product@1a8f392 2017-10-03 20:54:56,735 INFO [main] (SpringCacheWithEhCacheTest.java:45) - IPhone ->com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product@1a8f392 2017-10-03 20:54:56,736 INFO [main] (SpringCacheWithEhCacheTest.java:47) - Refreshing all products 2017-10-03 20:54:56,741 INFO [main] (ProductServiceImpl.java:40) - <!----------Entering getByName()---------------------> 2017-10-03 20:54:56,741 INFO [main] (SpringCacheWithEhCacheTest.java:50) - IPhone [after refresh]->com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product@1a8f392 2017-10-03 20:54:56,742 INFO [main] (SpringCacheWithEhCacheTest.java:51) - IPhone [after refresh]->com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product@1a8f392 2017-10-03 20:54:56,742 INFO [main] (SpringCacheWithEhCacheTest.java:52) - IPhone [after refresh]->com.xgj.cache.springCacheAnno.CompleteDemoWithEhCache.domain.Product@1a8f392 2017-10-03 20:54:56,742 INFO [main] (AbstractApplicationContext.java:984) - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7bd1a567: startup date [Tue Oct 03 20:54:55 BOT 2017]; root of context hierarchy 2017-10-03 20:54:56,744 INFO [main] (EhCacheManagerFactoryBean.java:187) - Shutting down EhCache CacheManager

查看ProductServiceImpl中的 getName方法中的@Cacheable注解可知

@Cacheable(cacheNames = "products", key = "#name", condition = "#name != 'HTC'", unless = "#result==null")

HTC不緩存, 結(jié)果為空不緩存。

查看輸出,第一次查詢 IPhone Samsung HTC ,分別從慢速設(shè)備中加載, 當(dāng)?shù)诙蔚谌尾樵僆Phone Samsung ,可以看到 并沒有輸出

logger.info("<!----------Entering getByName()--------------------->");

可知,其從緩存中加載。

因?yàn)椴痪彺鍴TC,所以每次查詢HTC都從會執(zhí)行方法,從慢速設(shè)備中查詢。

當(dāng)調(diào)用service.updateProduct(product); 我們使用的@CachePut注解更新緩存, 然后service.getByName(“IPhone”),緩存沒有被清空,所以依然是從緩存中獲取。

隨后,service.refreshAllProducts(); 將緩存全部清掉,再此查詢service.getByName(“IPhone”),然后再此查詢可以看到輸出了<!----------Entering getByName()--------------------->,緊接著的第二次第三次,是從緩存中獲取的數(shù)據(jù).


源碼

代碼已托管到Github—> https://github.com/yangshangwei/SpringMaster

總結(jié)

以上是生活随笔為你收集整理的Spring Cache抽象-使用Java类注解的方式整合EhCache的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。