从同一bean的另一个方法调用缓存的方法时,Spring缓存不工作。
这里有一个例子来清楚地解释我的问题。
配置:
<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"/>
缓存服务:
@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);
...
}
}
结果:
aService.getEmployeeData(someDate);
output: Cache is not being used
aService.getEmployeeData(someDate);
output:
aService.getEmployeeEnrichedData(someDate);
output: Cache is not being used
方法调用在第二次调用中使用缓存。但是,当在AService类中调用get雇员数据
方法时(在get雇员数据
中),Cache未被使用。
这就是SpringCache的工作原理还是我遗漏了什么?
下面的例子是我用来从同一个bean中命中代理的,它类似于@marioeis'的解决方案,但我发现它更具可读性(可能不是:-)。无论如何,我喜欢将@Cacheable注释保持在服务级别:
@Service
@Transactional(readOnly=true)
public class SettingServiceImpl implements SettingService {
@Inject
private SettingRepository settingRepository;
@Inject
private ApplicationContext applicationContext;
@Override
@Cacheable("settingsCache")
public String findValue(String name) {
Setting setting = settingRepository.findOne(name);
if(setting == null){
return null;
}
return setting.getValue();
}
@Override
public Boolean findBoolean(String name) {
String value = getSpringProxy().findValue(name);
if (value == null) {
return null;
}
return Boolean.valueOf(value);
}
/**
* Use proxy to hit cache
*/
private SettingService getSpringProxy() {
return applicationContext.getBean(SettingService.class);
}
...
另请参见在Springbean中启动新事务
自Spring 4.3以来,通过使用@Resource
注释上的自自动布线可以解决该问题:
@Component
@CacheConfig(cacheNames = "SphereClientFactoryCache")
public class CacheableSphereClientFactoryImpl implements SphereClientFactory {
/**
* 1. Self-autowired reference to proxified bean of this class.
*/
@Resource
private SphereClientFactory self;
@Override
@Cacheable(sync = true)
public SphereClient createSphereClient(@Nonnull TenantConfig tenantConfig) {
// 2. call cached method using self-bean
return self.createSphereClient(tenantConfig.getSphereClientConfig());
}
@Override
@Cacheable(sync = true)
public SphereClient createSphereClient(@Nonnull SphereClientConfig clientConfig) {
return CtpClientConfigurationUtils.createSphereClient(clientConfig);
}
}
我相信这就是它的工作原理。根据我记得读过的内容,生成了一个代理类,它截取所有请求并用缓存值响应,但是同一个类中的“内部”调用将不会获得缓存值。
从…起https://code.google.com/p/ehcache-spring-annotations/wiki/UsingCacheable
只有通过代理进来的外部方法调用才会被拦截。这意味着自调用(实际上,目标对象中的一个方法调用目标对象的另一个方法)不会在运行时导致实际的缓存拦截,即使调用的方法被标记为@Cacheable。
问题内容: 从同一bean的另一个方法调用缓存的方法时,Spring缓存不起作用。 这是一个示例,可以清楚地说明我的问题。 组态: 缓存的服务: 结果: 该方法调用使用缓存在第二次调用预期。但是,在类中()中调用该方法时,则未使用Cache。 这是Spring缓存的工作方式还是我缺少什么? 问题答案: 我相信这是这样的。从我记得阅读的内容来看,生成了一个代理类,该代理类可以拦截所有请求并使用缓存的
可能是问题似乎是重复的其他,但我已经检查了其他类似的问题,并尝试解决,但没有任何工作。 我正在使用缓存注释对服务类进行注释,如下所示: 我正在另一个服务类中自动生成CacheFacade。当我从那个类调用addRequest时,它可以工作,但当我调用getRequest时,它没有被调用,我尝试在那里添加日志和调试点,但流没有在那里。 这是我调用缓存服务类的主要服务类: 谁能告诉我,我做错了什么,为
当我从not bean类中的方法调用Cacheable方法时,我突然发现@Cacheable不起作用。 请在下面找到我的代码,并帮助我什么是问题或我错过的东西。
问题内容: 我是python的新手。我试图在类中将值从一种方法传递给另一种方法。我搜索了该问题,但无法获得适当的解决方案。因为在我的代码中,“ if”正在调用类的方法“ on_any_event”,而该方法反过来应该调用我的另一个方法“ dropbox_fn”,该方法利用了“ on_any_event”中的值。如果“dropbox_fn”方法在类之外,它将起作用吗? 我将用代码说明。 这里的主要问
问题内容: 在Bruce Eckel的“ Thinking In Java,第四版”的第428页(有关类型信息的章节)中,具有以下示例: 也许我有点累,但是我看不到add()方法中对add()的调用是如何工作的。我一直认为它应该有一个引用,或者是一个静态方法(并且我在ArrayList或List中找不到静态add())。我想念什么? 我只是为自己测试,发现这可行: 问题答案: Java为这样的方法
我试图从同一个类中调用方法: 希望的结果也被缓存,但是注释被忽略,并且每次都执行方法。 我是做错了什么,还是故意的?