我正在使用Spring和EhCache
我有以下方法
@Override
@Cacheable(value="products", key="#root.target.PRODUCTS")
public Set<Product> findAll() {
return new LinkedHashSet<>(this.productRepository.findAll());
}
Run Code Online (Sandbox Code Playgroud)
我有其他使用@Cacheable和@CachePut以及@CacheEvict的方法.
现在,假设数据库返回100个产品并且它们被缓存key="#root.target.PRODUCTS"
,然后其他方法将插入 - 更新 - 删除项目到数据库中.因此,通过它缓存的产品key="#root.target.PRODUCTS"
不再相同,例如数据库.
我的意思是,检查以下两种方法,他们能够更新/删除一个项目,同一项目缓存在另一个key="#root.target.PRODUCTS"
@Override
@CachePut(value="products", key="#product.id")
public Product update(Product product) {
return this.productRepository.save(product);
}
@Override
@CacheEvict(value="products", key="#id")
public void delete(Integer id) {
this.productRepository.delete(id);
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否可以通过更新/删除位于缓存中的项目key="#root.target.PRODUCTS"
,如果产品已更新,则为100,如果删除了产品,则为499.
我的观点是,我想避免以下情况:
@Override
@CachePut(value="products", key="#product.id")
@CacheEvict(value="products", key="#root.target.PRODUCTS")
public Product update(Product product) {
return this.productRepository.save(product);
}
@Override
@Caching(evict={
@CacheEvict(value="products", key="#id"),
@CacheEvict(value="products", key="#root.target.PRODUCTS")
})
public void delete(Integer id) {
this.productRepository.delete(id); …
Run Code Online (Sandbox Code Playgroud) 我在@org.springframework.cache.annotation.Cachable
注释方面遇到问题:
@Bean
public ConcurrentMapCache cache() {
return new ConcurrentMapCache(CACHE);
}
@Cacheable(CACHE)
public String getApi() {
return "api";
}
@Cacheable(CACHE)
public String getUrl() {
return "url";
}
Run Code Online (Sandbox Code Playgroud)
用法:
assertEquals("api", service.getApi()); //OK
assertEquals("url", service.getUrl()); //FAILURE. this returns also "api"
Run Code Online (Sandbox Code Playgroud)
那么,如果方法签名不包含任何输入参数,为什么@Cachable 不通过方法名称创建缓存结果?
我从缓存中获取价值时遇到问题.
java.lang.RuntimeException: java.lang.ClassCastException: com.mycom.admin.domain.User cannot be cast to com.mycom.admin.domain.User
Run Code Online (Sandbox Code Playgroud)
缓存配置
@Configuration
@EnableCaching
@AutoConfigureAfter(value = { MetricsConfiguration.class, DatabaseConfiguration.class })
@Profile("!" + Constants.SPRING_PROFILE_FAST)
public class MemcachedCacheConfiguration extends CachingConfigurerSupport {
private final Logger log = LoggerFactory.getLogger(MemcachedCacheConfiguration.class);
@Override
@Bean
public CacheManager cacheManager() {
ExtendedSSMCacheManager cacheManager = new ExtendedSSMCacheManager();
try {
List<SSMCache> list = new ArrayList<>();
list.add(new SSMCache(defaultCache("apiCache"), 86400, false));
cacheManager.setCaches(list);
} catch (Exception e) {
e.printStackTrace();
}
return cacheManager;
}
@Override
public CacheResolver cacheResolver() {
return null;
}
@Override
public CacheErrorHandler errorHandler() {
return …
Run Code Online (Sandbox Code Playgroud) 我有一个方法:
@Cacheable(key = "#jobId")
public Optional<JobInfo> getJobById(String jobId) {
log.info("Querying for job " + jobId);
counterService.increment("queryJobById");
Job job = jobsRepository.findOne(jobId);
if (job != null) {
return Optional.of(createDTOFromJob(job));
}
return Optional.empty();
}
Run Code Online (Sandbox Code Playgroud)
当我尝试检索缓存的项目时,我收到以下异常:
2016-01-18 00:01:10 ERROR [trace =,span =] http-nio-8021-exec-2 [dispatcherServlet]:182 - Servlet [dispatcherServlet]的Servlet.service()在路径[]的上下文中抛出异常[请求处理失败; 嵌套异常是org.springframework.data.redis.serializer.SerializationException:无法序列化; 嵌套异常是org.springframework.core.serializer.support.SerializationFailedException:无法使用DefaultSerializer序列化对象; 嵌套异常是java.lang.IllegalArgumentException:DefaultSerializer需要一个Serializable有效负载,但是收到一个类型为[java.util.Optional]的对象,其根本原因是java.lang.IllegalArgumentException:DefaultSerializer需要一个Serializable有效负载但是收到了一个类型为[java的对象] .util.Optional]
我正在为maven多模块项目开发缓存实现(exstremescale),我在其中添加了maven依赖项
<dependency>
<groupId>com.ibm.extremescale</groupId>
<artifactId>ogclient</artifactId>
<version>8.6.0.20150901-215917</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
添加了缓存注释
@Override
@Cacheable(value = "productDetails", key = "#productId + #orgId")
public Product productRead(final String productId, final String productKey, final String orgId, final CRApplicationEnum sourceSystem) throws IntegrationException {
Run Code Online (Sandbox Code Playgroud)
缓存manager.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:p="http://www.springframework.org/schema/p"
xmlns:cache="http://www.springframework.org/schema/cache"
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">
<cache:annotation-driven />
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager" primary="true">
<property name="caches">
<set>
<bean class="com.ibm.websphere.objectgrid.spring.ObjectGridCache"
p:name="eventDetails" p:map-name="${iev.eventDetails.mapName}"
p:object-grid-client-ref="wxsGridClient" />
<bean class="com.ibm.websphere.objectgrid.spring.ObjectGridCache"
p:name="eventValidationDetails" p:map-name="${iev.eventValidationDetails.mapName}"
p:object-grid-client-ref="wxsGridClient" />
<bean class="com.ibm.websphere.objectgrid.spring.ObjectGridCache"
p:name="productDetails" p:map-name="${ipr.productDetails.mapName}"
p:object-grid-client-ref="wxsGridClient" />
</set>
</property>
</bean>
<bean id="wxsCSDomain"
class="com.ibm.websphere.objectgrid.spring.ObjectGridCatalogServiceDomainBean"
p:catalog-service-endpoints="${xscale.catalogServiceEndpoint}" /> …
Run Code Online (Sandbox Code Playgroud) 我正在使用带有 spring 注释的咖啡因缓存提供程序,当条目\xe2\x80\x99s 放入缓存或驱逐或缓存上发生的任何活动时,我无法看到来自 caffeinecachemanager 的日志。我是否必须明确提及属性启用或禁用咖啡因日志?
\n\n任何人都可以帮助解决以下问题吗?\n当 @cachable 填充缓存时如何记录消息?\n当缓存条目从缓存中逐出时如何记录?\n有什么方法可以检查以缓存名称存储的所有缓存条目吗?\ n使用spring注解和CaffeineCacheManager时是否需要AOP配置。?如果是这样,请帮助示例。
\n我想缓存一个具有可选参数的简单 getter 的结果(下面示例中的 user-agent)。如何在不考虑可选用户代理参数的情况下指示创建密钥?
@Cacheable(value="bookCache")
public Book getBooks(@RequestHeader(value = "user-agent", required = false) String userAgent)
...
Run Code Online (Sandbox Code Playgroud) 鉴于我有 Spring Data 存储库并且我在方法上放置了Cacheable注释findAll
:
@Repository
@CacheConfig(cacheNames = TEMPLATE_CACHE)
public interface TemplateRepository extends JpaRepository<Template, Long> {
@Override
@Cacheable
List<Template> findAll();
}
Run Code Online (Sandbox Code Playgroud)
Intellij IDEA 显示警告:
Spring Team recommends that you only annotate concrete classes (and methods of concrete classes) with the @Cache* annotation, as opposed to annotating interfaces.
You certainly can place the @Cache* annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. …
Run Code Online (Sandbox Code Playgroud) 在 Spring Boot 2.1 中,我使用 Java 配置在配置文件中定义 RedisCacheManager bean。一切正常,但我有时想禁用它,例如在测试中。Spring Boot 提供了spring.cache.type=NONE
禁用缓存的功能,根据此文档。然而,这个属性将不起作用,因为我已经定义了一个 CacheManager,因此 Spring Boot 不会配置我想要的 NoOpCacheManager (有一个@ConditionalOnMissingBean(CacheManager.class)
onNoOpCacheConfiguration
的优先级低于RedisCacheConfiguration
)。
在定义缓存时,无论提供者是什么(例如 Caffeine),我们通常将它们定义为 beans,然后由 Spring Boot 的自动配置将其解析为SimpleCacheManager
. 例如
@Bean
public Cache myCache() {
return new CaffeineCache(
"my-cache",
Caffeine.newBuilder()
.maximumSize(10)
.build());
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这对于 Redis 来说是不可能的,因为它的Cache
实现RedisCache
不是公开的。
我们喜欢做的另一件事是定义一个 bean CacheManagerCustomizer<?>
,例如使用 Caffeine
@Bean
public CacheManagerCustomizer<CaffeineCacheManager> caffeineCacheManager() {
return cacheManager -> cacheManager
.setCaffeine(Caffeine.newBuilder()
.expireAfterWrite(1, TimeUnit.MINUTES));
}
Run Code Online (Sandbox Code Playgroud)
同样,这对于 Redis 来说是不可能的,因为它RedisCacheManager
是不可变的 …
spring spring-test spring-data-redis spring-boot spring-cache
我有一个具有以下属性的 Spring Boot 应用程序:
spring.cache.type: redis
spring.redis.host: <hostname>
spring.redis.port: <hostport>
Run Code Online (Sandbox Code Playgroud)
现在,如果远程主机发生故障,应用程序也会因连接错误而失败。在这种情况下,我的缓存不是我的应用程序的核心,但它仅用于性能,我希望 spring 简单地绕过它并转到数据库检索其数据。
我发现这可以通过定义自定义 errorHandler 方法来实现,但为了做到这一点,我必须实现 CachingConfigurer bean...但这也迫使我重写每个方法(例如缓存管理器、缓存解析器、ecc. )。
@Configuration
public class CacheConfiguration implements CachingConfigurer{
@Override
public CacheManager cacheManager() {
// TODO Auto-generated method stub
return null;
}
@Override
public CacheResolver cacheResolver() {
// TODO Auto-generated method stub
return null;
}
...
@Override
public CacheErrorHandler errorHandler() {
// the only method I need, maybe
return null;
}
Run Code Online (Sandbox Code Playgroud)
我想避免这种情况......我只需要一种方法来告诉 spring“缓存崩溃了,但没关系:假装你根本没有缓存”
spring-cache ×10
spring ×8
caching ×5
java ×4
spring-boot ×3
caffeine ×1
ehcache ×1
jhipster ×1
key ×1
memcached ×1
spring-3 ×1
spring-data ×1
spring-test ×1