0

在尝试使用内联刷新实现我自己的缓存加载器时。加载的此缓存正在使用 RefreshAheadCacheFactory

如所述

http://terracotta.org/documentation/4.1/bigmemorymax/api/refresh-ahead#scheduled-refresh-ahead

&

http://www.ehcache.org/generated/2.9.0/html/ehc-all/#page/Ehcache_Documentation_Set%2Fco-dec_creating_a_decorator_2.html

尝试添加自己的密钥时收到错误消息:

@Cacheable(key="myKey" , value = "myCache")

错误是:

org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Field or property 'myKey' cannot be found on object of type 'org.springframework.cache.interceptor.CacheExpressionRootObject'
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:208)
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:72)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:93)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:88)
    at org.springframework.cache.interceptor.ExpressionEvaluator.key(ExpressionEvaluator.java:80)
    at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.generateKey(CacheAspectSupport.java:464)
    at org.springframework.cache.interceptor.CacheAspectSupport.inspectCacheables(CacheAspectSupport.java:291)
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:198)
    at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:66)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
    at ehcache.MyCache$$EnhancerByCGLIB$$4aeb3b9c.tester(<generated>)
    at ehcache.TestEhcache.testCache(TestEhcache.java:21)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

如何将密钥“myKey”添加到缓存中?

我想我错误地设置了自定义缓存加载器。如何实现 loadAll 方法。这是我的实现:

public Map loadAll(Collection keys, Object argument) {
    // TODO Auto-generated method stub

    return new HashMap<String , String>();
}

这个 HashMap 是否应该包含键“myKey”?

当我自定义此方法时:

public Map loadAll(Collection keys, Object argument) {
// TODO Auto-generated method stub
 Map map = new HashMap<String , String>();
 map.put("myKey", "test");

return map;

}

我收到同样的错误。

所有代码和配置:

弹簧-ehcache.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
    xmlns:cache="http://www.springframework.org/schema/cache"
     xmlns:p="http://www.springframework.org/schema/p"
     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
     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
    <cache:annotation-driven />
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
        p:cache-manager-ref="ehcache" />
    <bean id="ehcache"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
        p:config-location="my-ehcache.xml" />

    <bean id="myCache" class="ehcache.MyCache"></bean>
</beans>

我的 ehcache.xml :

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <defaultCache eternal="true" maxElementsInMemory="100"
        overflowToDisk="false" />
    <cache name="myCache" maxElementsInMemory="10" eternal="true"
        overflowToDisk="false">

  <cacheLoaderFactory class="MyCacheLoaderFactory" properties="myKey" 
    />

        <cacheDecoratorFactory 
            class="net.sf.ehcache.constructs.refreshahead.RefreshAheadCacheFactory"
            properties="timeToRefreshSeconds=10,
      batchSize=5,
      numberOfThreads=4,
      maximumBacklogItems=5,
      evictOnLoadMiss=true" />

    </cache>
</ehcache>

package ehcache;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-ehcache.xml")
public class TestEhcache {

    @Test
    public void testCache(){

        while(true){


            long t1 = System.currentTimeMillis();

            System.out.println(myCache.tester());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            long t2 = System.currentTimeMillis();

            System.out.println("Exc time : "+(t2-t1));
        }
    }


    @Autowired
    private MyCache myCache;

}



package ehcache;

import org.springframework.cache.annotation.Cacheable;

public class MyCache {

    @Cacheable(key="myKey" , value = "myCache")
    public String tester() {

        System.out.println("in cache");
        ExpensiveOperation expensiveOperation = new ExpensiveOperation();
        String ret = expensiveOperation.doThis();

        return ret;
    }

}

package ehcache;

public class ExpensiveOperation {

    public String doThis() {

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return "test";
    }

}

import java.util.Properties;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.loader.CacheLoader;

public class MyCacheLoaderFactory extends
        net.sf.ehcache.loader.CacheLoaderFactory {

        @Override
        public CacheLoader createCacheLoader(Ehcache cache, Properties properties) {

            return new MyCacheLoader();

        }

    }

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import net.sf.ehcache.CacheException;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Status;
import net.sf.ehcache.loader.CacheLoader;


public class MyCacheLoader implements CacheLoader {

    public Object load(Object key) throws CacheException {
        // TODO Auto-generated method stub
        return load(key, null);
    }

    public Map loadAll(Collection keys) {
        // TODO Auto-generated method stub

        System.out.println("in loadall");

        return loadAll(keys , null);
    }

    public Object load(Object key, Object argument) {

        System.out.println("in load");
        // TODO Auto-generated method stub
        return "my object";
    }

    public Map loadAll(Collection keys, Object argument) {
        // TODO Auto-generated method stub
         Map map = new HashMap<String , String>();
         map.put("myKey", "test");

        return map;
    }

    public String getName() {
        // TODO Auto-generated method stub
        return null;
    }

    public CacheLoader clone(Ehcache cache) throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        return null;
    }

    public void init() {
        // TODO Auto-generated method stub

    }

    public void dispose() throws CacheException {
        // TODO Auto-generated method stub

    }

    public Status getStatus() {
        // TODO Auto-generated method stub
        return null;
    }

}
4

1 回答 1

1

首先,您需要查看 Spring Cache 文档,尤其是本节。您对注释的使用无效,这就是您看到 Spring 异常的原因。

其次,您需要真正实施CacheLoader. 这个类将通过访问您的数据库、Web 服务以及任何可以查询记录系统以根据该键获取数据的方式将键转换为键值对。这纯粹是特定于应用程序的,取决于您的用例。

第三,您需要更好地了解您在 Ehcache XML 中指定的属性是什么,因为在myKey那里没有什么意义。

还有一些其他问题需要解决,但了解上述前两个问题至关重要。

于 2014-11-19T13:57:26.917 回答