1. Gambaran keseluruhan
Dalam artikel ini, kami akan memperkenalkan Ehcache, cache berasaskan Java sumber terbuka yang banyak digunakan. Ia mempunyai memori dan kedai cakera, pendengar, pemuat cache, RESTful dan SOAP API dan ciri-ciri lain yang sangat berguna.
Untuk menunjukkan bagaimana caching dapat mengoptimumkan aplikasi kita, kita akan membuat kaedah mudah yang akan mengira nilai persegi nombor yang disediakan. Pada setiap panggilan, kaedah akan memanggil kaedah calculSquareOfNumber (nombor int) dan mencetak mesej maklumat ke konsol.
Dengan contoh mudah ini, kami ingin menunjukkan bahawa pengiraan nilai kuasa dua dilakukan hanya sekali, dan setiap panggilan lain dengan nilai input yang sama akan menghasilkan hasil dari cache.
Penting untuk diperhatikan bahawa kita memberi tumpuan sepenuhnya kepada Ehcache itu sendiri (tanpa Spring); jika anda ingin melihat bagaimana Ehcache berfungsi dengan Spring, sila baca artikel ini.
2. Pergantungan Maven
Untuk menggunakan Ehcache, kita perlu menambahkan kebergantungan Maven ini:
org.ehcache ehcache 3.1.3
Versi terbaru artifak Ehcache boleh didapati di sini.
3. Konfigurasi Cache
Ehcache boleh dikonfigurasi dengan dua cara:
- Cara pertama adalah melalui Java POJO di mana semua parameter konfigurasi dikonfigurasikan melalui Ehcache API
- Cara kedua adalah konfigurasi melalui fail XML di mana kita dapat mengkonfigurasi Ehcache mengikut definisi skema yang disediakan
Dalam artikel ini, kami akan menunjukkan kedua pendekatan - Java dan juga konfigurasi XML.
3.1. Konfigurasi Java
Subseksyen ini akan menunjukkan betapa mudahnya mengkonfigurasi Ehcache dengan POJO. Kami juga akan membuat kelas pembantu untuk konfigurasi dan ketersediaan cache yang lebih mudah:
public class CacheHelper { private CacheManager cacheManager; private Cache squareNumberCache; public CacheHelper() { cacheManager = CacheManagerBuilder .newCacheManagerBuilder().build(); cacheManager.init(); squareNumberCache = cacheManager .createCache("squaredNumber", CacheConfigurationBuilder .newCacheConfigurationBuilder( Integer.class, Integer.class, ResourcePoolsBuilder.heap(10))); } public Cache getSquareNumberCacheFromCacheManager() { return cacheManager.getCache("squaredNumber", Integer.class, Integer.class); } // standard getters and setters }
Untuk memulakan cache kami, pertama, kita perlu menentukan objek Ehcache CacheManager . Dalam contoh ini, kita sedang mencipta satu cache lalai squaredNumber " dengan newCacheManagerBuilder () API .
Cache hanya akan memetakan Integer kunci untuk Integer nilai.
Perhatikan bagaimana, sebelum kita mulai menggunakan cache yang ditentukan, kita perlu menginisialisasi objek CacheManager dengan metode init () .
Akhirnya, untuk mendapatkan cache kami, kami hanya dapat menggunakan getCache () API dengan nama, kunci dan jenis nilai cache yang disediakan.
Dengan beberapa baris tersebut, kami membuat cache pertama kami yang kini tersedia untuk aplikasi kami.
3.2. Konfigurasi XML
Objek konfigurasi dari subseksyen 3.1. sama dengan menggunakan konfigurasi XML ini:
java.lang.Integer java.lang.Integer 10
Dan untuk memasukkan cache ini dalam aplikasi Java kita, kita perlu membaca file konfigurasi XML di Java:
URL myUrl = getClass().getResource(xmlFile); XmlConfiguration xmlConfig = new XmlConfiguration(myUrl); CacheManager myCacheManager = CacheManagerBuilder .newCacheManager(xmlConfig);
4. Ujian Ehcache
Pada bahagian 3. kami menunjukkan bagaimana anda dapat menentukan cache sederhana untuk tujuan anda. Untuk menunjukkan bahawa caching benar-benar berfungsi, kami akan membuat kelas SquaredCalculator yang akan mengira nilai kuasa dua input yang disediakan, dan menyimpan nilai yang dikira dalam cache.
Sudah tentu, jika cache sudah mengandungi nilai yang dihitung, kami akan mengembalikan nilai cache dan mengelakkan pengiraan yang tidak diperlukan:
public class SquaredCalculator { private CacheHelper cache; public int getSquareValueOfNumber(int input) { if (cache.getSquareNumberCache().containsKey(input)) { return cache.getSquareNumberCache().get(input); } System.out.println("Calculating square value of " + input + " and caching result."); int squaredValue = (int) Math.pow(input, 2); cache.getSquareNumberCache().put(input, squaredValue); return squaredValue; } //standard getters and setters; }
Untuk menyelesaikan senario ujian kami, kami juga memerlukan kod yang akan mengira nilai persegi:
@Test public void whenCalculatingSquareValueAgain_thenCacheHasAllValues() { for (int i = 10; i < 15; i++) { assertFalse(cacheHelper.getSquareNumberCache().containsKey(i)); System.out.println("Square value of " + i + " is: " + squaredCalculator.getSquareValueOfNumber(i) + "\n"); } for (int i = 10; i < 15; i++) { assertTrue(cacheHelper.getSquareNumberCache().containsKey(i)); System.out.println("Square value of " + i + " is: " + squaredCalculator.getSquareValueOfNumber(i) + "\n"); } }
Sekiranya kami menjalankan ujian, kami akan mendapat keputusan ini di konsol kami:
Calculating square value of 10 and caching result. Square value of 10 is: 100 Calculating square value of 11 and caching result. Square value of 11 is: 121 Calculating square value of 12 and caching result. Square value of 12 is: 144 Calculating square value of 13 and caching result. Square value of 13 is: 169 Calculating square value of 14 and caching result. Square value of 14 is: 196 Square value of 10 is: 100 Square value of 11 is: 121 Square value of 12 is: 144 Square value of 13 is: 169 Square value of 14 is: 196
Seperti yang anda perhatikan, kaedah hitung () hanya melakukan pengiraan pada panggilan pertama. Pada panggilan kedua, semua nilai dijumpai di cache dan dikembalikan daripadanya.
5. Pilihan Konfigurasi Ehcache yang lain
Semasa kami membuat cache kami dalam contoh sebelumnya, itu adalah cache sederhana tanpa pilihan khas. Bahagian ini akan menunjukkan pilihan lain yang berguna dalam pembuatan cache.
5.1. Ketekunan Cakera
Sekiranya terdapat terlalu banyak nilai untuk disimpan ke dalam cache, kita dapat menyimpan beberapa nilai tersebut pada cakera keras.
PersistentCacheManager persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder() .with(CacheManagerBuilder.persistence(getStoragePath() + File.separator + "squaredValue")) .withCache("persistent-cache", CacheConfigurationBuilder .newCacheConfigurationBuilder(Integer.class, Integer.class, ResourcePoolsBuilder.newResourcePoolsBuilder() .heap(10, EntryUnit.ENTRIES) .disk(10, MemoryUnit.MB, true)) ) .build(true); persistentCacheManager.close();
Daripada CacheManager lalai , sekarang kami menggunakan PersistentCacheManager yang akan mempertahankan semua nilai yang tidak dapat disimpan ke dalam memori.
Dari konfigurasi, kita dapat melihat bahawa cache akan menyimpan 10 elemen ke dalam memori dan ia akan memperuntukkan 10MB pada cakera keras untuk kegigihan.
5.2. Tamat Tempoh Data
Sekiranya kita menyimpan banyak data dalam bentuk cache, adalah wajar kita menyimpan data yang di-cache untuk beberapa jangka masa sehingga kita dapat menghindari penggunaan memori yang besar.
Ehcache mengawal kesegaran data melalui antara muka Expiry :
CacheConfiguration cacheConfiguration = CacheConfigurationBuilder .newCacheConfigurationBuilder(Integer.class, Integer.class, ResourcePoolsBuilder.heap(100)) .withExpiry(Expirations.timeToLiveExpiration(Duration.of(60, TimeUnit.SECONDS))).build();
Dalam cache ini, semua data akan hidup selama 60 saat dan selepas jangka masa tersebut, data akan dihapus dari memori.
6. Kesimpulannya
Dalam artikel ini, kami menunjukkan cara menggunakan cache Ehcache sederhana dalam aplikasi Java.
Dalam contoh kami, kami melihat bahawa cache yang hanya dikonfigurasi dapat menjimatkan banyak operasi yang tidak diperlukan. Kami juga menunjukkan bahawa kami dapat mengkonfigurasi cache melalui POJO dan XML dan Ehcache mempunyai beberapa ciri yang bagus - seperti ketekunan dan luput data.
Seperti biasa, kod dari artikel ini boleh didapati di GitHub.