Add two level of caching
This commit is contained in:
parent
c5a3c01108
commit
43a168a525
|
@ -0,0 +1,90 @@
|
|||
package com.baeldung.caching.multicache;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.AnnotationCacheOperationSource;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.caffeine.CaffeineCache;
|
||||
import org.springframework.cache.interceptor.CacheInterceptor;
|
||||
import org.springframework.cache.interceptor.CacheOperationSource;
|
||||
import org.springframework.cache.support.SimpleCacheManager;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
public class CacheConfig {
|
||||
|
||||
@Value("${spring.redis.host}")
|
||||
private String redisHost;
|
||||
|
||||
@Value("${spring.redis.port}")
|
||||
private int redisPort;
|
||||
|
||||
@Bean
|
||||
public CaffeineCache caffeineCacheConfig() {
|
||||
return new CaffeineCache("customerCache", Caffeine.newBuilder()
|
||||
.expireAfterWrite(Duration.ofMinutes(1))
|
||||
.initialCapacity(1)
|
||||
.maximumSize(2000)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public CacheManager caffeineCacheManager() {
|
||||
SimpleCacheManager manager = new SimpleCacheManager();
|
||||
manager.setCaches(Arrays.asList(
|
||||
caffeineCacheConfig()));
|
||||
return manager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheManager redisCacheManager() {
|
||||
return RedisCacheManager.RedisCacheManagerBuilder
|
||||
.fromConnectionFactory(redisConnectionFactory())
|
||||
.withCacheConfiguration("customerCache", cacheConfiguration())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisConnectionFactory redisConnectionFactory() {
|
||||
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
|
||||
redisStandaloneConfiguration.setHostName(redisHost);
|
||||
redisStandaloneConfiguration.setPort(redisPort);
|
||||
return new LettuceConnectionFactory(redisStandaloneConfiguration);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisCacheConfiguration cacheConfiguration() {
|
||||
return RedisCacheConfiguration.defaultCacheConfig()
|
||||
.entryTtl(Duration.ofMinutes(60))
|
||||
.disableCachingNullValues()
|
||||
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheInterceptor cacheInterceptor() {
|
||||
CacheInterceptor interceptor = new CustomerCacheInterceptor(caffeineCacheManager());
|
||||
interceptor.setCacheOperationSources(cacheOperationSource());
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheOperationSource cacheOperationSource() {
|
||||
return new AnnotationCacheOperationSource();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.caching.multicache;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Setter
|
||||
public class Customer implements Serializable {
|
||||
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String email;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.caching.multicache;
|
||||
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.interceptor.CacheInterceptor;
|
||||
import org.springframework.data.redis.cache.RedisCache;
|
||||
|
||||
public class CustomerCacheInterceptor extends CacheInterceptor {
|
||||
|
||||
private final CacheManager caffeineCacheManager;
|
||||
|
||||
public CustomerCacheInterceptor(CacheManager caffeineCacheManager) {
|
||||
this.caffeineCacheManager = caffeineCacheManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Cache.ValueWrapper doGet(Cache cache, Object key) {
|
||||
Cache.ValueWrapper existingCacheValue = super.doGet(cache, key);
|
||||
|
||||
if (cache.getClass() == RedisCache.class) {
|
||||
Cache caffeineCache = caffeineCacheManager.getCache(cache.getName());
|
||||
if (existingCacheValue != null && caffeineCache != null && caffeineCache.get(key) == null) {
|
||||
caffeineCache.putIfAbsent(key, existingCacheValue.get());
|
||||
}
|
||||
}
|
||||
|
||||
return existingCacheValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.caching.multicache;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class CustomerController {
|
||||
|
||||
private final CustomerService customerService;
|
||||
|
||||
@Autowired
|
||||
public CustomerController(CustomerService customerService) {
|
||||
this.customerService = customerService;
|
||||
}
|
||||
|
||||
@GetMapping("/customer/{id}")
|
||||
public Customer getCustomer(@PathVariable String id) {
|
||||
return customerService.getCustomer(id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.baeldung.caching.multicache;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class CustomerRepository {
|
||||
|
||||
private final Map<String, Customer> customerMap = new HashMap<>();
|
||||
|
||||
public Customer getCustomerById(String id) {
|
||||
return customerMap.get(id);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void setupCustomerRepo() {
|
||||
Customer product1 = getCustomer("100001", "name1", "name1@mail.com");
|
||||
customerMap.put("100001", product1);
|
||||
|
||||
Customer product2 = getCustomer("100002", "name2", "name2@mail.com");
|
||||
customerMap.put("100002", product2);
|
||||
|
||||
Customer product3 = getCustomer("100003", "name3", "name3@mail.com");
|
||||
customerMap.put("100003", product3);
|
||||
|
||||
Customer product4 = getCustomer("100004", "name4", "name4@mail.com");
|
||||
customerMap.put("100004", product4);
|
||||
|
||||
Customer product5 = getCustomer("100005", "name5", "name5@mail.com");
|
||||
customerMap.put("100005", product5);
|
||||
}
|
||||
|
||||
private static Customer getCustomer(String id, String name, String email) {
|
||||
Customer customer = new Customer();
|
||||
customer.setId(id);
|
||||
customer.setName(name);
|
||||
customer.setEmail(email);
|
||||
|
||||
return customer;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.caching.multicache;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.Caching;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class CustomerService {
|
||||
|
||||
private final CustomerRepository customerRepository;
|
||||
|
||||
@Autowired
|
||||
public CustomerService(CustomerRepository customerRepository) {
|
||||
this.customerRepository = customerRepository;
|
||||
}
|
||||
|
||||
@Caching(cacheable = {
|
||||
@Cacheable(cacheNames = "customerCache", cacheManager = "caffeineCacheManager"),
|
||||
@Cacheable(cacheNames = "customerCache", cacheManager = "redisCacheManager")
|
||||
})
|
||||
public Customer getCustomer(String id) {
|
||||
return customerRepository.getCustomerById(id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.caching.multicache;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class MultipleCachingApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MultipleCachingApplication.class, args);
|
||||
}
|
||||
}
|
|
@ -9,5 +9,6 @@ spring.jpa.hibernate.ddl-auto=update
|
|||
#setting cache TTL
|
||||
caching.spring.hotelListTTL=43200
|
||||
# Connection details
|
||||
#spring.redis.host=localhost
|
||||
#spring.redis.port=6379
|
||||
spring.redis.host=localhost
|
||||
spring.redis.port=6379
|
||||
spring.main.allow-bean-definition-overriding=true
|
||||
|
|
Loading…
Reference in New Issue