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
|
#setting cache TTL
|
||||||
caching.spring.hotelListTTL=43200
|
caching.spring.hotelListTTL=43200
|
||||||
# Connection details
|
# Connection details
|
||||||
#spring.redis.host=localhost
|
spring.redis.host=localhost
|
||||||
#spring.redis.port=6379
|
spring.redis.port=6379
|
||||||
|
spring.main.allow-bean-definition-overriding=true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user