diff --git a/pom.xml b/pom.xml index e8ff86665c..4dba0da173 100644 --- a/pom.xml +++ b/pom.xml @@ -663,6 +663,7 @@ spring-dispatcher-servlet spring-drools + spring-ehcache spring-ejb spring-exceptions @@ -882,6 +883,7 @@ spring-data-rest spring-dispatcher-servlet spring-drools + spring-ehcache spring-freemarker persistence-modules/spring-hibernate-3 persistence-modules/spring-hibernate4 @@ -1370,6 +1372,7 @@ spring-dispatcher-servlet spring-drools + spring-ehcache spring-ejb spring-exceptions diff --git a/spring-ehcache/.gitignore b/spring-ehcache/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/spring-ehcache/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-ehcache/README.md b/spring-ehcache/README.md new file mode 100644 index 0000000000..749441375e --- /dev/null +++ b/spring-ehcache/README.md @@ -0,0 +1,7 @@ +## Spring Ehcache Example Project + +A simple example of using ehcache with spring-boot. + +### Relevant Articles: +- [Spring Boot Ehcache Example](http://www.baeldung.com/spring-ehcache) + diff --git a/spring-ehcache/checkstyle.xml b/spring-ehcache/checkstyle.xml new file mode 100644 index 0000000000..85063a7570 --- /dev/null +++ b/spring-ehcache/checkstyle.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/spring-ehcache/pom.xml b/spring-ehcache/pom.xml new file mode 100644 index 0000000000..b8378617c5 --- /dev/null +++ b/spring-ehcache/pom.xml @@ -0,0 +1,87 @@ + + 4.0.0 + spring-ehcache + 0.1-SNAPSHOT + spring-ehcache + jar + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-cache + + + javax.cache + cache-api + + + org.ehcache + ehcache + + + + + spring-ehcache + + + src/main/resources + true + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle-maven-plugin.version} + + checkstyle.xml + + + + + check + + + + + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle-maven-plugin.version} + + checkstyle.xml + + + + + + + + 3.0.0 + false + + + diff --git a/spring-ehcache/src/main/java/com/baeldung/cachetest/Application.java b/spring-ehcache/src/main/java/com/baeldung/cachetest/Application.java new file mode 100644 index 0000000000..a1ce7a5317 --- /dev/null +++ b/spring-ehcache/src/main/java/com/baeldung/cachetest/Application.java @@ -0,0 +1,13 @@ +package com.baeldung.cachetest; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} \ No newline at end of file diff --git a/spring-ehcache/src/main/java/com/baeldung/cachetest/config/CacheConfig.java b/spring-ehcache/src/main/java/com/baeldung/cachetest/config/CacheConfig.java new file mode 100644 index 0000000000..3cf2309cb9 --- /dev/null +++ b/spring-ehcache/src/main/java/com/baeldung/cachetest/config/CacheConfig.java @@ -0,0 +1,57 @@ +package com.baeldung.cachetest.config; + +import java.math.BigDecimal; +import java.time.Duration; + +import javax.cache.CacheManager; + +import org.ehcache.config.CacheConfiguration; +import org.ehcache.config.ResourcePools; +import org.ehcache.config.builders.CacheConfigurationBuilder; +import org.ehcache.config.builders.CacheEventListenerConfigurationBuilder; +import org.ehcache.config.builders.ExpiryPolicyBuilder; +import org.ehcache.config.builders.ResourcePoolsBuilder; +import org.ehcache.config.units.EntryUnit; +import org.ehcache.config.units.MemoryUnit; +import org.ehcache.event.EventType; +import org.ehcache.jsr107.Eh107Configuration; +import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableCaching +public class CacheConfig { + + private static final int ON_HEAP_CACHE_SIZE_ENTRIES = 2; + private static final int OFF_HEAP_CACHE_SIZE_MB = 10; + private static final int CACHE_EXPIRY_SECONDS = 30; + + @Bean + public JCacheManagerCustomizer jcacheManagerCustomizer() { + return new JCacheManagerCustomizer() { + + @Override + public void customize(CacheManager cacheManager) { + ResourcePools resourcePools = ResourcePoolsBuilder.newResourcePoolsBuilder() + .heap(ON_HEAP_CACHE_SIZE_ENTRIES, EntryUnit.ENTRIES) + .offheap(OFF_HEAP_CACHE_SIZE_MB, MemoryUnit.MB).build(); + + CacheEventListenerConfigurationBuilder eventLoggerConfig = CacheEventListenerConfigurationBuilder + .newEventListenerConfiguration(new CacheEventLogger(), EventType.CREATED, EventType.EXPIRED) + .unordered().asynchronous(); + + CacheConfiguration cacheConfiguration = CacheConfigurationBuilder + .newCacheConfigurationBuilder(Long.class, BigDecimal.class, resourcePools) + .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(CACHE_EXPIRY_SECONDS))) + .add(eventLoggerConfig).build(); + + cacheManager.createCache("squareCache", + Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration)); + + } + }; + } + +} diff --git a/spring-ehcache/src/main/java/com/baeldung/cachetest/config/CacheEventLogger.java b/spring-ehcache/src/main/java/com/baeldung/cachetest/config/CacheEventLogger.java new file mode 100644 index 0000000000..c8ead85f1e --- /dev/null +++ b/spring-ehcache/src/main/java/com/baeldung/cachetest/config/CacheEventLogger.java @@ -0,0 +1,18 @@ +package com.baeldung.cachetest.config; + +import org.ehcache.event.CacheEvent; +import org.ehcache.event.CacheEventListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CacheEventLogger implements CacheEventListener { + + private static final Logger log = LoggerFactory.getLogger(CacheEventLogger.class); + + @Override + public void onEvent(CacheEvent cacheEvent) { + log.info("Cache event {} for item with key {}. Old value = {}, New value = {}", cacheEvent.getType(), + cacheEvent.getKey(), cacheEvent.getOldValue(), cacheEvent.getNewValue()); + } + +} diff --git a/spring-ehcache/src/main/java/com/baeldung/cachetest/rest/NumberController.java b/spring-ehcache/src/main/java/com/baeldung/cachetest/rest/NumberController.java new file mode 100644 index 0000000000..4115c34cc4 --- /dev/null +++ b/spring-ehcache/src/main/java/com/baeldung/cachetest/rest/NumberController.java @@ -0,0 +1,29 @@ +package com.baeldung.cachetest.rest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.cachetest.service.NumberService; + +@RestController +@RequestMapping(path = "/number", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) +public class NumberController { + + private final static Logger log = LoggerFactory.getLogger(NumberController.class); + + @Autowired + private NumberService numberService; + + @GetMapping(path = "/square/{number}") + public String getThing(@PathVariable Long number) { + log.info("call numberService to square {}", number); + return String.format("{\"square\": %s}", numberService.square(number)); + } + +} diff --git a/spring-ehcache/src/main/java/com/baeldung/cachetest/service/NumberService.java b/spring-ehcache/src/main/java/com/baeldung/cachetest/service/NumberService.java new file mode 100644 index 0000000000..bcd930f5e1 --- /dev/null +++ b/spring-ehcache/src/main/java/com/baeldung/cachetest/service/NumberService.java @@ -0,0 +1,22 @@ +package com.baeldung.cachetest.service; + +import java.math.BigDecimal; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +@Service +public class NumberService { + + private final static Logger log = LoggerFactory.getLogger(NumberService.class); + + @Cacheable(value = "squareCache", key = "#number", condition = "#number>10") + public BigDecimal square(Long number) { + BigDecimal square = BigDecimal.valueOf(number).multiply(BigDecimal.valueOf(number)); + log.info("square of {} is {}", number, square); + return square; + } + +}