[英]cache2k and Generic T do not play nice together
在 cache2k 用户指南中, §2.3。 Cache Aside有一个关于 cache-aside 的代码示例和句子。
Cache<String, String> routeToAirline = new Cache2kBuilder<String, String>() {} .name("routeToAirline") .build(); private String findFavoriteAirline(String origin, String destination) { // expensive operation to find the best airline for this route // for example, ask all friends... } public String lookupFavoirteAirline(String origin, String destination) { String route = origin + "-" + destination; String airline = routeToAirline.peek(route); if (airline == null) { airline = findFavoriteAirline(origin, destination); routeToAirline.put(route, airline); } return airline; }
上述模式称为缓存旁白。
我喜欢“太棒了......我喜欢缓存 Aside 模式”。 所以我尝试使用泛型而不是硬编码(值)类型来实现一个。
我想出了这个使用泛型。 我注入了“获取”物品的方法(供应商)。 完全可重用的代码!
package mypackage;
import java.util.function.Supplier;
import org.cache2k.Cache;
import org.cache2k.Cache2kBuilder;
//import mypackage.interfaces.IGenericCacheAside;
public class Cache2kGenericCacheAside<TEntity> ////implements IGenericCacheAside<TEntity> {
public final String CacheKeyPrefix = "GenericCacheAsidePrefix";
private volatile Cache<String, TEntity> theCache = null; /* static not allowed for TEntity */
public TEntity GetCacheAsideItem(String uniqueIdentifier, long itemLifeMiliseconds,
final Supplier<TEntity> valueFactory) {
this.initiateCacheObject();
String cacheKey = this.GetFullCacheKey(uniqueIdentifier);
TEntity cachedOrFreshItem = this.GetFromCache(cacheKey, itemLifeMiliseconds, valueFactory);
return cachedOrFreshItem;
}
public TEntity RemoveCacheAsideItem(String uniqueIdentifier) {
TEntity removedItem = null;
String cacheKey = this.GetFullCacheKey(uniqueIdentifier);
if (this.theCache.containsKey(uniqueIdentifier)) {
removedItem = this.theCache.peekAndRemove(cacheKey);
}
return removedItem;
}
private void initiateCacheObject(/* long duration, TimeUnit tu, long capacity */) {
if (null == this.theCache) {
theCache = new Cache2kBuilder<String, TEntity>() {
}.name("myCache").eternal(true).build();
}
}
private TEntity GetFromCache(String cacheKey, long millis, final Supplier<TEntity> valueFactory) {
TEntity cachedOrFreshItem = theCache.peek(cacheKey);
if (cachedOrFreshItem == null) {
cachedOrFreshItem = valueFactory.get();
theCache.put(cacheKey, cachedOrFreshItem);
theCache.expireAt(cacheKey, millis);
}
return cachedOrFreshItem;
}
private String GetFullCacheKey(String uniqueIdentifier) {
String returnValue = CacheKeyPrefix + uniqueIdentifier;
return returnValue;
}
}
我收到一个运行时错误:
java.lang.IllegalArgumentException:运行时类型不可用,得到:TEntity
我想我可能已经偶然发现了这个以前未知的类型擦除世界。
有没有办法实现这个 Generic-CacheAside 代码? 这个隐藏的宝石(擦除)是可怕的。
<dependency>
<groupId>org.cache2k</groupId>
<artifactId>cache2k-api</artifactId>
<version>1.2.0.Final</version>
</dependency>
附加:
这是一个例子。 基本上,任何时候我都需要缓存一个不受检索参数驱动的“东西”。 在下面的示例中,我正在缓存 SystemSetting(s)。 没有参数来驱动检索。
private static int NewedUpCounter = 0;
private static int CurrentRunCacheReads = 0;
private static void RunCacheAsideStuff() {
/* example ONLY. use construction-injection for "real" code */
////IGenericCacheAside<Collection<SystemSetting>> igca = new Cache2kGenericCacheAside<Collection<SystemSetting>>();
/* or */
Cache2kGenericCacheAside<Collection<SystemSetting>> igca = new Cache2kGenericCacheAside<Collection<SystemSetting>>();
for (int i = 0; i < 20; i++) {
/* in the below, it shows how the "time to keep in the cache" might change over time */
int cacheMilliseconds = 2500 + (500 * i);
System.out.println(String.format(" cacheMilliseconds=%1s",
cacheMilliseconds));
Collection<SystemSetting> cacheAsideSettings = igca.GetCacheAsideItem("myuniqueIdentifier", cacheMilliseconds,
TimeUnit.MILLISECONDS, App::CreateDummySystemSettings);
if (null != cacheAsideSettings) {
System.out.println("--------------");
System.out.println(String.format(" CurrentRunCacheReads=%1s",
++CurrentRunCacheReads));
System.out.println(String.format(" Cached Collection<SystemSetting> Read .. size=%1s",
cacheAsideSettings.size()));
for (SystemSetting sett : cacheAsideSettings) {
System.out.println(String.format(
"cacheAsideSettings !! SystemSetting.Key=%1s, SystemSetting.Value = %2s, i = %3s , Time= %4s",
sett.getSystemSettingKey(), sett.getSettingValue(), i, LocalDateTime.now()));
}
System.out.println("--------------");
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println(String.format("NewedUpCounter=%1s",
NewedUpCounter));
}
private static Collection<SystemSetting> CreateDummySystemSettings() {
NewedUpCounter++;
CurrentRunCacheReads=0;
long LOWER_RANGE = 10000; // assign lower range value
long UPPER_RANGE = 20000; // assign upper range value
Random random = new Random();
long randomValue = LOWER_RANGE + (long) (random.nextDouble() * (UPPER_RANGE - LOWER_RANGE));
Collection<SystemSetting> returnItems = new ArrayList<>();
for (int i = 101; i < 104; i++) {
SystemSetting newSetting = new SystemSetting();
newSetting.setSystemSettingKey(i);
newSetting.setSettingValue(String.format("ValueOf%1s*", randomValue));
returnItems.add(newSetting);
}
System.out.println(String.format("NEW Collection<SystemSetting> CREATED !! size=%1s ************************************************", returnItems.size()));
return returnItems;
}
和输出。 显示项目/缓存时间的示例可以更改。
cacheMilliseconds=2500
NEW Collection<SystemSetting> CREATED !! size=3 ************************************************
--------------
CurrentRunCacheReads=1
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14000*, i = 0 , Time= 2018-09-28T13:04:14.043
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14000*, i = 0 , Time= 2018-09-28T13:04:14.052
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14000*, i = 0 , Time= 2018-09-28T13:04:14.052
--------------
cacheMilliseconds=3000
--------------
CurrentRunCacheReads=2
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14000*, i = 1 , Time= 2018-09-28T13:04:15.052
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14000*, i = 1 , Time= 2018-09-28T13:04:15.053
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14000*, i = 1 , Time= 2018-09-28T13:04:15.053
--------------
cacheMilliseconds=3500
--------------
CurrentRunCacheReads=3
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14000*, i = 2 , Time= 2018-09-28T13:04:16.054
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14000*, i = 2 , Time= 2018-09-28T13:04:16.054
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14000*, i = 2 , Time= 2018-09-28T13:04:16.054
--------------
cacheMilliseconds=4000
NEW Collection<SystemSetting> CREATED !! size=3 ************************************************
--------------
CurrentRunCacheReads=1
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17155*, i = 3 , Time= 2018-09-28T13:04:17.055
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17155*, i = 3 , Time= 2018-09-28T13:04:17.055
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17155*, i = 3 , Time= 2018-09-28T13:04:17.055
--------------
cacheMilliseconds=4500
--------------
CurrentRunCacheReads=2
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17155*, i = 4 , Time= 2018-09-28T13:04:18.056
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17155*, i = 4 , Time= 2018-09-28T13:04:18.056
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17155*, i = 4 , Time= 2018-09-28T13:04:18.056
--------------
cacheMilliseconds=5000
--------------
CurrentRunCacheReads=3
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17155*, i = 5 , Time= 2018-09-28T13:04:19.057
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17155*, i = 5 , Time= 2018-09-28T13:04:19.058
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17155*, i = 5 , Time= 2018-09-28T13:04:19.058
--------------
cacheMilliseconds=5500
--------------
CurrentRunCacheReads=4
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17155*, i = 6 , Time= 2018-09-28T13:04:20.058
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17155*, i = 6 , Time= 2018-09-28T13:04:20.058
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17155*, i = 6 , Time= 2018-09-28T13:04:20.058
--------------
cacheMilliseconds=6000
NEW Collection<SystemSetting> CREATED !! size=3 ************************************************
--------------
CurrentRunCacheReads=1
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17444*, i = 7 , Time= 2018-09-28T13:04:21.059
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17444*, i = 7 , Time= 2018-09-28T13:04:21.060
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17444*, i = 7 , Time= 2018-09-28T13:04:21.060
--------------
cacheMilliseconds=6500
--------------
CurrentRunCacheReads=2
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17444*, i = 8 , Time= 2018-09-28T13:04:22.060
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17444*, i = 8 , Time= 2018-09-28T13:04:22.060
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17444*, i = 8 , Time= 2018-09-28T13:04:22.060
--------------
cacheMilliseconds=7000
--------------
CurrentRunCacheReads=3
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17444*, i = 9 , Time= 2018-09-28T13:04:23.060
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17444*, i = 9 , Time= 2018-09-28T13:04:23.060
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17444*, i = 9 , Time= 2018-09-28T13:04:23.060
--------------
cacheMilliseconds=7500
--------------
CurrentRunCacheReads=4
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17444*, i = 10 , Time= 2018-09-28T13:04:24.060
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17444*, i = 10 , Time= 2018-09-28T13:04:24.061
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17444*, i = 10 , Time= 2018-09-28T13:04:24.061
--------------
cacheMilliseconds=8000
--------------
CurrentRunCacheReads=5
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17444*, i = 11 , Time= 2018-09-28T13:04:25.061
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17444*, i = 11 , Time= 2018-09-28T13:04:25.061
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17444*, i = 11 , Time= 2018-09-28T13:04:25.061
--------------
cacheMilliseconds=8500
--------------
CurrentRunCacheReads=6
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17444*, i = 12 , Time= 2018-09-28T13:04:26.063
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17444*, i = 12 , Time= 2018-09-28T13:04:26.063
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17444*, i = 12 , Time= 2018-09-28T13:04:26.064
--------------
cacheMilliseconds=9000
NEW Collection<SystemSetting> CREATED !! size=3 ************************************************
--------------
CurrentRunCacheReads=1
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14680*, i = 13 , Time= 2018-09-28T13:04:27.065
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14680*, i = 13 , Time= 2018-09-28T13:04:27.065
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14680*, i = 13 , Time= 2018-09-28T13:04:27.066
--------------
cacheMilliseconds=9500
--------------
CurrentRunCacheReads=2
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14680*, i = 14 , Time= 2018-09-28T13:04:28.066
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14680*, i = 14 , Time= 2018-09-28T13:04:28.066
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14680*, i = 14 , Time= 2018-09-28T13:04:28.066
--------------
cacheMilliseconds=10000
--------------
CurrentRunCacheReads=3
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14680*, i = 15 , Time= 2018-09-28T13:04:29.067
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14680*, i = 15 , Time= 2018-09-28T13:04:29.067
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14680*, i = 15 , Time= 2018-09-28T13:04:29.067
--------------
cacheMilliseconds=10500
--------------
CurrentRunCacheReads=4
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14680*, i = 16 , Time= 2018-09-28T13:04:30.068
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14680*, i = 16 , Time= 2018-09-28T13:04:30.068
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14680*, i = 16 , Time= 2018-09-28T13:04:30.068
--------------
cacheMilliseconds=11000
--------------
CurrentRunCacheReads=5
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14680*, i = 17 , Time= 2018-09-28T13:04:31.068
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14680*, i = 17 , Time= 2018-09-28T13:04:31.068
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14680*, i = 17 , Time= 2018-09-28T13:04:31.068
--------------
cacheMilliseconds=11500
--------------
CurrentRunCacheReads=6
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14680*, i = 18 , Time= 2018-09-28T13:04:32.068
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14680*, i = 18 , Time= 2018-09-28T13:04:32.068
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14680*, i = 18 , Time= 2018-09-28T13:04:32.068
--------------
cacheMilliseconds=12000
--------------
CurrentRunCacheReads=7
Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14680*, i = 19 , Time= 2018-09-28T13:04:33.069
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14680*, i = 19 , Time= 2018-09-28T13:04:33.069
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14680*, i = 19 , Time= 2018-09-28T13:04:33.069
--------------
NewedUpCounter=4 /* this last one not accurate since its "bailing out */
匿名类创建表达式new Cache2kBuilder<String, String>() {}
用作“超类型标记”以在运行时表示参数化类型。 他们这样做的方法是创建一个扩展参数化类型的子类(通常是匿名类),其中类型参数是在编译时固定(硬编码)的具体类型。 由于类的超类是类声明的一部分,所以它与类文件的声明部分中的泛型信息一起存储,并且可以在运行时通过反射检索这些信息。
请注意,在运行时可以从类文件中检索到的内容正是在编译时硬编码的内容。 这就是new Cache2kBuilder<String, TEntity>() {}
不起作用的原因——在编译时源代码中硬编码的是有一个名为TEntity
的类型变量,而不是一个具体的类。
Cache2k 提供了一种不同的方法来构造Cache2kBuilder
如果该类不能在编译时修复,并且只能在运行时知道:
theCache = Cache2kBuilder.of(String.class, entityClass)
.name("myCache").eternal(true).build();
其中entityClass
是Class<TEntity>
,它是运行时实体类的类对象。 因此,您还必须传入实体的Class
对象,而不仅仅是它的Supplier
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.