Let us implement another way of object caching through these steps:
- Aside from logging and auditing, aspects can also be used to trigger caching. To enable Ehcache in Spring 5.0, include the following Maven dependency in the pom.xml:
<dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>3.3.1</version> </dependency>
- Define all the caches to be used by the application in an XML file named ehcache.xml. Place this configuration file in src/main/resources:
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <diskStore path="C://ch05cached" /> <cache name="employeesCache" maxEntriesLocalHeap="500" maxEntriesLocalDisk="500" eternal="false" diskSpoolBufferSizeMB="20" timeToIdleSeconds="300" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LFU" transactionalMode="off"> <persistence strategy="localTempSwap" /> </cache> </ehcache>
If the operating system used is macOS or Linux, point diskStore to the desired folder location using the correct file system path.
- Open the SpringDispatcherConfig in org.packt.aop.transaction.dispatcher and initialize the following org.springframework.cache.ehcache.EhCacheManagerFactoryBean and org.springframework.cache.CacheManager beans to the container:
import org.springframework.cache.CacheManager; import org.springframework.cache.ehcache.EhCacheCacheManager; import org.springframework.cache.ehcache.EhCacheManagerFactoryBean; // refer to sources @EnableWebMvc @ComponentScan(basePackages="org.packt.aop.transaction") @PropertySource("classpath:config/jdbc.properties") @Configuration public class SpringDispatcherConfig extends WebMvcConfigurerAdapter{ @Inject private ResourceLoader resourceLoader; // refer to sources @Bean public CacheManager cacheManager(){ CacheManager cm = new EhCacheCacheManager( ehCacheCacheManager().getObject()); return cm; } @Bean public EhCacheManagerFactoryBean ehCacheCacheManager() { EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean(); cmfb.setConfigLocation(resourceLoader .getResource("classpath:ehcache.xml")); cmfb.setShared(true); return cmfb; } }
- Create an @Aspect that will intercept the getEmployees() method in EmployeeDaoImpl and will manage the caching of its return value, which is a List<Employee>:
import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Element; // refer to sources @Component @Aspect public class CacheListenerAspect { @Autowired private CacheManager cacheManager; private Logger logger = Logger.getLogger(CacheListenerAspect.class); @Around("execution(* org.packt.aop.transaction.dao .impl.EmployeeDaoImpl.getEmployees(..))") public Object cacheMonitor(ProceedingJoinPoint joinPoint) throws Throwable { logger.info("executing " + joinPoint.getSignature().getName()); Cache cache = cacheManager.getCache("employeesCache"); logger.info("cache detected is " + cache.getName()); logger.info("begin caching....."); String key = joinPoint.getSignature().getName(); logger.info(key); if(cache.get(key) == null){ logger.info("caching new Object....."); Object result = joinPoint.proceed(); cache.put(new Element(key, result)); return result; }else{ logger.info("getting cached Object....."); return cache.get(key).getObjectValue(); } } }
- Save all files. Stop the Tomcat server first and then start it again due to cache installation. Then clean, build, and deploy the project.