Cache musim semi tidak berfungsi saat memanggil metode cache dari metode lain dari kacang yang sama.
Berikut adalah contoh untuk menjelaskan masalah saya dengan jelas.
Konfigurasi:
<cache:annotation-driven cache-manager="myCacheManager" />
<bean id="myCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="myCache" />
</bean>
<!-- Ehcache library setup -->
<bean id="myCache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:shared="true">
<property name="configLocation" value="classpath:ehcache.xml"></property>
</bean>
<cache name="employeeData" maxElementsInMemory="100"/>
Layanan dalam cache:
@Named("aService")
public class AService {
@Cacheable("employeeData")
public List<EmployeeData> getEmployeeData(Date date){
..println("Cache is not being used");
...
}
public List<EmployeeEnrichedData> getEmployeeEnrichedData(Date date){
List<EmployeeData> employeeData = getEmployeeData(date);
...
}
}
Hasil:
aService.getEmployeeData(someDate);
output: Cache is not being used
aService.getEmployeeData(someDate);
output:
aService.getEmployeeEnrichedData(someDate);
output: Cache is not being used
The getEmployeeData
penggunaan metode panggilan-cache employeeData
dalam panggilan kedua seperti yang diharapkan. Tetapi ketika getEmployeeData
metode dipanggil di dalam AService
kelas (dalam getEmployeeEnrichedData
), Cache tidak digunakan.
Apakah ini cara kerja cache musim semi atau saya melewatkan sesuatu?
someDate
param?Jawaban:
Saya yakin begitulah cara kerjanya. Dari apa yang saya ingat pernah membaca, ada kelas proxy yang dihasilkan yang mencegat semua permintaan dan merespons dengan nilai yang di-cache, tetapi panggilan 'internal' dalam kelas yang sama tidak akan mendapatkan nilai yang di-cache.
Dari https://code.google.com/p/ehcache-spring-annotations/wiki/UsingCacheable
sumber
@Cacheable
ke DAO :( Jika Anda memiliki solusi yang lebih baik, beri tahu saya, terima kasih.@Resource
self-autowiring, lihat contoh stackoverflow.com/a/48867068/907576@Cacheable
metode eksternal seharusnyapublic
, tidak berfungsi pada metode paket-privat. Menemukannya dengan cara yang sulit.Sejak Spring 4.3, masalah tersebut dapat diselesaikan menggunakan self-autowiring melalui
@Resource
anotasi:sumber
4.3.17
dan tidak berhasil, panggilan untukself
tidak melalui proxy dan cache (masih) dilewati.Contoh di bawah ini adalah apa yang saya gunakan untuk menekan proxy dari dalam kacang yang sama, ini mirip dengan solusi @ mario-eis, tetapi saya merasa sedikit lebih mudah dibaca (mungkin bukan :-). Bagaimanapun, saya ingin menyimpan anotasi @Cacheable di tingkat layanan:
Lihat juga Memulai transaksi baru di Spring bean
sumber
applicationContext.getBean(SettingService.class);
, adalah kebalikan dari injeksi ketergantungan. Saya sarankan untuk menghindari gaya itu.Inilah yang saya lakukan untuk proyek kecil dengan hanya penggunaan marginal dari pemanggilan metode dalam kelas yang sama. Dokumentasi dalam kode sangat disarankan, karena mungkin terlihat aneh bagi rekan kerja. Tapi mudah untuk menguji, sederhana, cepat untuk dicapai dan membuat saya tidak perlu menggunakan instrumentasi AspectJ sepenuhnya. Namun, untuk penggunaan yang lebih berat, saya akan menyarankan solusi AspectJ.
sumber
Dalam Kasus saya, saya menambahkan variabel:
Jadi saya memanggil
getEmployeeData
metode dengan menggunakanaService
}
Ini akan menggunakan cache dalam kasus ini.
sumber
Gunakan tenun statis untuk membuat proxy di sekitar kacang Anda. Dalam hal ini bahkan metode 'internal' akan bekerja dengan benar
sumber
<iajc
kompiler (dari ant) yang menyelesaikan semua aspek kebutuhan untuk kelas yang dapat disimpan dalam cache.Saya menggunakan kacang dalam internal (
FactoryInternalCache
) dengan cache nyata untuk tujuan ini:sumber
solusi termudah sejauh ini hanya dengan referensi seperti ini:
sumber