java 如何使用缓存
缓存的基本概念
缓存是一种临时存储数据的技术,用于提高应用程序的性能和响应速度。通过将频繁访问的数据存储在内存中,可以减少对数据库或其他慢速存储介质的访问次数。
Java中的缓存实现方式
使用HashMap实现简单缓存
创建一个简单的缓存可以使用Java的HashMap。这种方式适合小规模应用或临时缓存需求。
import java.util.HashMap;
import java.util.Map;
public class SimpleCache<K, V> {
private final Map<K, V> cache = new HashMap<>();
public void put(K key, V value) {
cache.put(key, value);
}
public V get(K key) {
return cache.get(key);
}
public void remove(K key) {
cache.remove(key);
}
public void clear() {
cache.clear();
}
}
使用Guava Cache
Google的Guava库提供了更强大的缓存功能,支持过期策略、缓存大小限制等。
添加Maven依赖:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
示例代码:
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
public class GuavaCacheExample {
public static void main(String[] args) {
Cache<String, String> cache = CacheBuilder.newBuilder()
.maximumSize(100)
.build();
cache.put("key1", "value1");
String value = cache.getIfPresent("key1");
System.out.println(value);
}
}
使用Caffeine Cache
Caffeine是一个高性能的Java缓存库,比Guava Cache更高效。
添加Maven依赖:
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.1</version>
</dependency>
示例代码:
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
public class CaffeineCacheExample {
public static void main(String[] args) {
Cache<String, String> cache = Caffeine.newBuilder()
.maximumSize(100)
.build();
cache.put("key1", "value1");
String value = cache.getIfPresent("key1");
System.out.println(value);
}
}
使用Ehcache
Ehcache是一个广泛使用的开源Java缓存库,支持磁盘持久化和分布式缓存。
添加Maven依赖:
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.9.7</version>
</dependency>
示例代码:
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
public class EhcacheExample {
public static void main(String[] args) {
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build();
cacheManager.init();
Cache<String, String> cache = cacheManager.createCache("myCache",
CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class,
ResourcePoolsBuilder.heap(100)));
cache.put("key1", "value1");
String value = cache.get("key1");
System.out.println(value);
cacheManager.close();
}
}
使用Spring Cache
Spring框架提供了缓存抽象,可以方便地集成各种缓存实现。
添加Maven依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
启用缓存:
@SpringBootApplication
@EnableCaching
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
使用缓存注解:
@Service
public class MyService {
@Cacheable("myCache")
public String getValue(String key) {
// 模拟耗时操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return "value_for_" + key;
}
@CacheEvict("myCache")
public void evictCache(String key) {
// 清除缓存
}
}
缓存策略选择
根据应用需求选择合适的缓存策略:
- 内存缓存:适合单机应用,数据量不大
- 分布式缓存:适合集群环境,如Redis
- 持久化缓存:需要数据持久化时使用,如Ehcache
缓存注意事项
- 缓存穿透:查询不存在的数据导致每次请求都打到数据库。解决方案:布隆过滤器或缓存空值。
- 缓存雪崩:大量缓存同时失效导致数据库压力剧增。解决方案:设置不同的过期时间。
- 缓存一致性:确保缓存与数据库数据一致。解决方案:双写策略或失效机制。
分布式缓存Redis
对于分布式系统,Redis是常用的缓存解决方案。
添加Maven依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置Redis:
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}
使用Redis缓存:
@Service
public class RedisService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void setValue(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}
public Object getValue(String key) {
return redisTemplate.opsForValue().get(key);
}
}






