Spring Cache (In-Memory) ======================== https://github.com/spring-boot-tutorials/spring-cache-in-memory In this article we will configure Spring Boot to connect to a `Cassandra `_ database. `Spring Boot supported cache providers `_: - Generic - JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others) - Hazelcast - Infinispan - Couchbase - Redis - Caffeine - Cache2k - Simple Create Initial Code Base ------------------------ - Go to https://start.spring.io/ - Add the following dependencies: - spring-boot-starter-cache - spring-boot-starter-web - lombok - Click `Generate` Dependencies ------------ Dependencies used in ``pom.xml`` .. code-block:: xml org.springframework.boot spring-boot-starter-cache org.springframework.boot spring-boot-starter-web org.projectlombok lombok true Configuration ------------- Let's create a new file ``src/main/java/com/example/spring_cache_abstraction/DefaultConfig.java`` .. code-block:: java @Configuration @EnableCaching public class DefaultConfig { public static final String CACHE_ADDRESS = "addresses"; public static final String CACHE_DIRECTORY = "directory"; @Bean public CacheManager cacheManager() { SimpleCacheManager cacheManager = new SimpleCacheManager(); cacheManager.setCaches(Arrays.asList( new ConcurrentMapCache(CACHE_DIRECTORY), new ConcurrentMapCache(CACHE_ADDRESS)) ); return cacheManager; } } Model ----- Let's create a new POJO ``src/main/java/com/example/spring_cache_abstraction/Customer.java`` .. code-block:: java @Getter @Setter @NoArgsConstructor @AllArgsConstructor @SuperBuilder public class Customer { private String name; } Service ------- Let's create a service class ``src/main/java/com/example/spring_cache_abstraction/DefaultService.java``: .. code-block:: java @Service public class DefaultService { /////////////// // CACHEABLE // /////////////// @Cacheable(value = CACHE_ADDRESS, key = "#customer.name") public String getCachedAddress(Customer customer) { System.out.println("inside cacheable function `getCachedAddress`"); return "address + " + customer.getName(); } @Cacheable(value = CACHE_DIRECTORY, key = "#customer.name") public String getCachedDirectory(Customer customer) { System.out.println("inside cacheable function `getCachedDirectory`"); return "address + " + customer.getName(); } ///////////////// // CACHE EVICT // ///////////////// @CacheEvict(value = CACHE_ADDRESS, allEntries = true) public void evictAllAddress() {} @CacheEvict(value = CACHE_ADDRESS, key = "#customer.name") public void evictSingleAddress(Customer customer) {} /////////////// // CACHE PUT // /////////////// // @CachePut is used to ensure that a method is always executed // and its result is then placed into the cache. Unlike @Cacheable, // @CachePut does not skip method execution if a value is already // present in the cache. Instead, it forces the method to run, and the // result of that execution is used to update the corresponding entry // in the cache. This is useful for scenarios where you need to guarantee // that the cache always reflects the latest state of data, such as // after an update operation. @CachePut(value = CACHE_ADDRESS, key = "#customer.name") public String getAddressAndCache(Customer customer) { System.out.println("inside cacheable function `getAddressAndCache`"); return "address + " + customer.getName(); } ///////////// // CACHING // ///////////// @Caching(evict = { @CacheEvict(value = CACHE_ADDRESS, allEntries = true), @CacheEvict(value = CACHE_DIRECTORY, allEntries = true), }) public void evictAllAddressAndDirectory() {} @Caching( cacheable = { @Cacheable(CACHE_ADDRESS), @Cacheable(value = CACHE_DIRECTORY)}, put = { @CachePut(CACHE_ADDRESS), @CachePut(CACHE_DIRECTORY),} ) public void unintelligible() {} ///////////////////////// // Conditional Caching // ///////////////////////// @CachePut(value="addresses", condition="#customer.name=='Tom'") public String getAddressConditional1(Customer customer) { return null; } @CachePut(value="addresses", unless="#result.length()<64") public String getAddressConditional2(Customer customer) { return null; } } Main ---- Now let's use this service. Go back to ``MainApplication.java`` and add the following: .. code-block:: java @SpringBootApplication public class SpringCacheAbstractionApplication implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(SpringCacheAbstractionApplication.class, args); } @Autowired DefaultService defaultService; @Override public void run(String... args) { List customers = List.of( new Customer("marcus"), new Customer("jesus"), new Customer("marcus"), new Customer("jesus"), new Customer("asher")); System.out.println("\nSTART ADDRESSES"); customers.forEach(c -> { System.out.println("Invoking cacheable function `getCachedAddress` for input param=" + c); defaultService.getCachedAddress(c); }); System.out.println("\nSTART DIRECTORY"); customers.forEach(c -> { System.out.println("Invoking cacheable function `getCachedDirectory` for input param=" + c); defaultService.getCachedDirectory(c); }); } } Run Application --------------- Open terminal at project root and execute the following: .. code-block:: sh mvn spring-boot:run There should be no errors and verify the output.