Bài viết này hướng dẫn cơ bản để làm data caching với Spring framework kết hợp với một framework phổ biến về caching là Ehchache. Thực ra thì Spring tự bản thân nó đã hổ trợ caching nhưng Ehcache framework cung cấp thêm một số tùy chỉnh như thời gian hết hạn (thời gian remove khỏi bộ nhớ cache).
- Ehcache 2.9
- Spring 4.2.7.RELEASE
- Maven 3
- JDK 1.8
- Spring tool suite/Eclipse
- Thư viện hỗ trợ
Thu viện hỗ trợ cho caching của Spring là spring-context.jar; để Spring hỗ trợ cho Ehcache caching cần thêm thư viện spring-context-support.jar.
pom.xml
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.7.RELEASE</version>
</dependency>
2. Cấu hình
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<cache:annotation-driven />
//your beans
</beans>
Hoặc bạn có thể sử dụng annotation @EnableCaching trong class config.
AppConfig.java
ehcache.xml
"1.0" encoding="UTF-8" xml version= <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" name="CM1" updateCheck="false" maxBytesLocalHeap="16M"> <!-- This is a default configuration, it is re-configured by the CacheConfiguration Spring Bean, using the properties from the resources/config/*.yml files. --> <diskStore path="java.io.tmpdir" /> <cache name="token" timeToLiveSeconds="5" /> </ehcache>
3. @Cacheable
Method với annotation @Cacheable thì khi nó được gọi nếu trong bộ nhớ cache có tồi tại giá trị tương ứng thì giá trị này được trả về mà không cần execute method; ngược lại thì execute nội dung method sau đó trả về kết quả đồng thời lưu giá trị đó vào bộ nhớ cache.
Như ở bước 3 class đang implement một interface. Đây là điểm mấu chốt quan trọng của caching, nếu không có interface thì cache sẽ không work. Mình đã gặp phải lỗi này nên hi vọng mọi người sẽ không bị.
AppConfig.java
@EnableCaching @Configuration @ComponentScan(basePackages = "com.itphuongha.example") @PropertySource(value = {"classpath:application.properties"}) @EnableScheduling
public class AppConfig { private final Logger log = LoggerFactory.getLogger(AppConfig.class); private net.sf.ehcache.CacheManager cacheManager;
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } @Bean
public CacheManager cacheManager(EhCacheManagerFactoryBean factory) { EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager(); cacheManager = factory.getObject(); ehCacheCacheManager.setCacheManager(cacheManager); return ehCacheCacheManager; } @Bean
public EhCacheManagerFactoryBean ehCacheCacheManager() { log.info("ehCacheCacheManager"); EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean(); cmfb.setConfigLocation(new ClassPathResource("ehcache.xml")); cmfb.setShared(true); return cmfb; }
ehcache.xml
"1.0" encoding="UTF-8" xml version= <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" name="CM1" updateCheck="false" maxBytesLocalHeap="16M"> <!-- This is a default configuration, it is re-configured by the CacheConfiguration Spring Bean, using the properties from the resources/config/*.yml files. --> <diskStore path="java.io.tmpdir" /> <cache name="token" timeToLiveSeconds="5" /> </ehcache>
- timeToLiveSeconds: thời gian tối đa (tính theo giây) mà một đối tượng tồn tại trong cache bất kể nó có được gọi tới hay không. Ví dụ: đối tượng được tạo lúc 07:00:00; và nó sẽ được remove khỏi cache lúc 07:00:05, bất kể có hay không.
- timeToIdleSeconds: thời gian tối đa (tính theo giây) mà một đối tượng tồn tại trong cache kể từ thời điểm cuối cùng nó được gọi hay sử dụng. Ví dụ: đối tượng được tạo lúc 07:00:00; lần cuối cùng nó được gọi truy cập tới là 08:00:00 sau 5s nếu không có truy cập khác thì sẽ được remove khỏi cache lúc 08:00:05.
Method với annotation @Cacheable thì khi nó được gọi nếu trong bộ nhớ cache có tồi tại giá trị tương ứng thì giá trị này được trả về mà không cần execute method; ngược lại thì execute nội dung method sau đó trả về kết quả đồng thời lưu giá trị đó vào bộ nhớ cache.
public class CachingDemo implements ICachingDemo { @Autowired private Environment environment; private static final JSONParser parser = new JSONParser();
@Override @Cacheable(value = "token", unless = "#result == null") public String getToken() { // get from other system, API return token; }4. Interface cho class caching class
Như ở bước 3 class đang implement một interface. Đây là điểm mấu chốt quan trọng của caching, nếu không có interface thì cache sẽ không work. Mình đã gặp phải lỗi này nên hi vọng mọi người sẽ không bị.
public interface ICachingDemo { String getToken(); }
Phuong Ha
Wow, amazing article
ReplyDelete