Polish cache code

This commit is contained in:
Phillip Webb
2015-06-04 00:51:20 -07:00
parent 412b7b9e50
commit d2f11c465e
22 changed files with 234 additions and 175 deletions

View File

@@ -16,8 +16,9 @@ the application starts a client invokes the service with a random code every 500
can look at the `/metrics` endpoint to review the cache statistics if your chosen
caching provider is supported.
== Using the JSR-107 annotations
== Using the JSR-107 annotations
The sample uses Spring's cache annotation. If you want to use the JSR-107 annotations
instead, simply add the `javax.cache:cache-api` dependency to the project. No further
configuration is necessary.
@@ -25,35 +26,40 @@ configuration is necessary.
NOTE: You can use the JSR-107 annotations with _any_ cache provider; a JSR-107 compliant
cache provider is not necessary.
== Using a different cache provider
== Using a different cache provider
Initially, the project does not define any caching library so the abstraction works
on simple `ConcurrentHashMap`-based caches. You can try out your favorite caching library
as explained below.
=== EhCache 2.x
=== EhCache 2.x
Simply add the `net.sf.ehcache:ehcache` dependency to the project. Since there is a
default `ehcache.xml` configuration file at the root of the classpath, it is automatically
used to configure the underlying `CacheManager`.
=== Hazelcast
=== Hazelcast
Both `com.hazelcast:hazelcast` and `com.hazelcast:hazelcast-spring` should be added to
the project to enable support for Hazelcast. Since there is a default `hazelcast.xml`
configuration file at the root of the classpath, it is used to automatically configure
the underlying `HazelcastInstance`.
=== Infinispan
=== Infinispan
Simply add the `org.infinispan:infinispan-spring4` dependency to enable support for
Infinispan. There is no default location that Infinispan uses to look for a config
file so if you don't specify anything it will bootstrap on a hardcoded default. You
can set the `spring.cache.infinispan.config` property to use the provided
`infinispan.xml` configuration instead.
=== JCache (JSR-107)
=== JCache (JSR-107)
If you want to configure your cache infrastructure via the standard, you need a compliant
implementation. You could try the following:
@@ -65,14 +71,16 @@ Since Spring Boot supports the native cache library and the JCache wrapper, you
should set the `spring.cache.type` property to `jcache` to specify that you want the
cache manager to be auto-configured that way.
=== Redis
=== Redis
Add the `spring-boot-starter-redis` and make sure it is configured properly (by default,
a redis instance with the default settings is expected on your local box).
=== Guava
=== Guava
Spring Boot does not provide any dependency management for _Guava_ so you'll have to add
the `com.google.guava:guava` dependency with a version. You can customize how caches are
created in different ways, see `application.properties` for an example and the
documentation for more details.
documentation for more details.

View File

@@ -24,7 +24,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- Only used to expose cache metrics -->
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -34,12 +33,14 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Additional cache providers
<!-- Additional cache providers (uncomment to try them) -->
<!--
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
-->
<!--
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
@@ -48,6 +49,8 @@
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-spring</artifactId>
</dependency>
-->
<!--
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-spring4</artifactId>
@@ -56,17 +59,20 @@
<groupId>org.infinispan</groupId>
<artifactId>infinispan-jcache</artifactId>
</dependency>
<dependency>
-->
<!--
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
-->
<!--
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Component;
@Component
public class CacheManagerCheck implements CommandLineRunner {
private final CacheManager cacheManager;
@Autowired
public CacheManagerCheck(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
@Override
public void run(String... strings) throws Exception {
SampleCacheApplication.logger.info("\n\n"
+ "=========================================================\n"
+ "Using cache manager: " + this.cacheManager.getClass().getName() + "\n"
+ "=========================================================\n\n");
}
}

View File

@@ -28,22 +28,26 @@ public class Country implements Serializable {
}
public String getCode() {
return code;
return this.code;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Country country = (Country) o;
return code.equals(country.code);
return this.code.equals(country.code);
}
@Override
public int hashCode() {
return code.hashCode();
return this.code.hashCode();
}
}

View File

@@ -18,46 +18,21 @@ package sample;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
@EnableCaching
@EnableScheduling
@SpringBootApplication
public class SampleCacheApplication {
private static final Logger logger = LoggerFactory.getLogger(SampleCacheApplication.class);
static final Logger logger = LoggerFactory.getLogger(SampleCacheApplication.class);
public static void main(String[] args) {
new SpringApplicationBuilder()
.sources(SampleCacheApplication.class)
.profiles("app")
.run(args);
}
@Component
static class CacheManagerCheck implements CommandLineRunner {
private final CacheManager cacheManager;
@Autowired
CacheManagerCheck(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
@Override
public void run(String... strings) throws Exception {
logger.info("\n\n" + "=========================================================\n"
+ "Using cache manager: " + this.cacheManager.getClass().getName() + "\n"
+ "=========================================================\n\n");
}
new SpringApplicationBuilder().sources(SampleCacheApplication.class)
.profiles("app").run(args);
}
}

View File

@@ -29,23 +29,26 @@ import org.springframework.stereotype.Component;
@Profile("app")
class SampleClient {
private static final List<String> SAMPLE_COUNTRY_CODES = Arrays.asList("AF", "AX", "AL", "DZ", "AS",
"AD", "AO", "AI", "AQ", "AG", "AR", "AM", "AW", "AU", "AT", "AZ", "BS", "BH", "BD", "BB", "BY",
"BE", "BZ", "BJ", "BM", "BT", "BO", "BQ", "BA", "BW", "BV", "BR", "IO", "BN", "BG", "BF", "BI",
"KH", "CM", "CA", "CV", "KY", "CF", "TD", "CL", "CN", "CX", "CC", "CO", "KM", "CG", "CD", "CK",
"CR", "CI", "HR", "CU", "CW", "CY", "CZ", "DK", "DJ", "DM", "DO", "EC", "EG", "SV", "GQ", "ER",
"EE", "ET", "FK", "FO", "FJ", "FI", "FR", "GF", "PF", "TF", "GA", "GM", "GE", "DE", "GH", "GI",
"GR", "GL", "GD", "GP", "GU", "GT", "GG", "GN", "GW", "GY", "HT", "HM", "VA", "HN", "HK", "HU",
"IS", "IN", "ID", "IR", "IQ", "IE", "IM", "IL", "IT", "JM", "JP", "JE", "JO", "KZ", "KE", "KI",
"KP", "KR", "KW", "KG", "LA", "LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK", "MG",
"MW", "MY", "MV", "ML", "MT", "MH", "MQ", "MR", "MU", "YT", "MX", "FM", "MD", "MC", "MN", "ME",
"MS", "MA", "MZ", "MM", "NA", "NR", "NP", "NL", "NC", "NZ", "NI", "NE", "NG", "NU", "NF", "MP",
"NO", "OM", "PK", "PW", "PS", "PA", "PG", "PY", "PE", "PH", "PN", "PL", "PT", "PR", "QA", "RE",
"RO", "RU", "RW", "BL", "SH", "KN", "LC", "MF", "PM", "VC", "WS", "SM", "ST", "SA", "SN", "RS",
"SC", "SL", "SG", "SX", "SK", "SI", "SB", "SO", "ZA", "GS", "SS", "ES", "LK", "SD", "SR", "SJ",
"SZ", "SE", "CH", "SY", "TW", "TJ", "TZ", "TH", "TL", "TG", "TK", "TO", "TT", "TN", "TR", "TM",
"TC", "TV", "UG", "UA", "AE", "GB", "US", "UM", "UY", "UZ", "VU", "VE", "VN", "VG", "VI", "WF",
"EH", "YE", "ZM", "ZW");
private static final List<String> SAMPLE_COUNTRY_CODES = Arrays.asList("AF", "AX",
"AL", "DZ", "AS", "AD", "AO", "AI", "AQ", "AG", "AR", "AM", "AW", "AU", "AT",
"AZ", "BS", "BH", "BD", "BB", "BY", "BE", "BZ", "BJ", "BM", "BT", "BO", "BQ",
"BA", "BW", "BV", "BR", "IO", "BN", "BG", "BF", "BI", "KH", "CM", "CA", "CV",
"KY", "CF", "TD", "CL", "CN", "CX", "CC", "CO", "KM", "CG", "CD", "CK", "CR",
"CI", "HR", "CU", "CW", "CY", "CZ", "DK", "DJ", "DM", "DO", "EC", "EG", "SV",
"GQ", "ER", "EE", "ET", "FK", "FO", "FJ", "FI", "FR", "GF", "PF", "TF", "GA",
"GM", "GE", "DE", "GH", "GI", "GR", "GL", "GD", "GP", "GU", "GT", "GG", "GN",
"GW", "GY", "HT", "HM", "VA", "HN", "HK", "HU", "IS", "IN", "ID", "IR", "IQ",
"IE", "IM", "IL", "IT", "JM", "JP", "JE", "JO", "KZ", "KE", "KI", "KP", "KR",
"KW", "KG", "LA", "LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK",
"MG", "MW", "MY", "MV", "ML", "MT", "MH", "MQ", "MR", "MU", "YT", "MX", "FM",
"MD", "MC", "MN", "ME", "MS", "MA", "MZ", "MM", "NA", "NR", "NP", "NL", "NC",
"NZ", "NI", "NE", "NG", "NU", "NF", "MP", "NO", "OM", "PK", "PW", "PS", "PA",
"PG", "PY", "PE", "PH", "PN", "PL", "PT", "PR", "QA", "RE", "RO", "RU", "RW",
"BL", "SH", "KN", "LC", "MF", "PM", "VC", "WS", "SM", "ST", "SA", "SN", "RS",
"SC", "SL", "SG", "SX", "SK", "SI", "SB", "SO", "ZA", "GS", "SS", "ES", "LK",
"SD", "SR", "SJ", "SZ", "SE", "CH", "SY", "TW", "TJ", "TZ", "TH", "TL", "TG",
"TK", "TO", "TT", "TN", "TR", "TM", "TC", "TV", "UG", "UA", "AE", "GB", "US",
"UM", "UY", "UZ", "VU", "VE", "VN", "VG", "VI", "WF", "EH", "YE", "ZM", "ZW");
private final CountryRepository countryService;
@@ -59,7 +62,8 @@ class SampleClient {
@Scheduled(fixedDelay = 500)
public void retrieveCountry() {
String randomCode = SAMPLE_COUNTRY_CODES.get(random.nextInt(SAMPLE_COUNTRY_CODES.size()));
String randomCode = SAMPLE_COUNTRY_CODES.get(this.random
.nextInt(SAMPLE_COUNTRY_CODES.size()));
System.out.println("Looking for country with code '" + randomCode + "'");
this.countryService.findByCode(randomCode);
}

View File

@@ -1,5 +1,3 @@
#
# Infinispan configuration file location.
#
@@ -16,4 +14,4 @@
#
# Guava configuration
#
#spring.cache.guava.spec=maximumSize=200,expireAfterAccess=600s
#spring.cache.guava.spec=maximumSize=200,expireAfterAccess=600s

View File

@@ -18,7 +18,6 @@ package sample;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.cache.Cache;
@@ -31,10 +30,9 @@ import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.IsNull.notNullValue;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {SampleCacheApplication.class})
@SpringApplicationConfiguration(classes = { SampleCacheApplication.class })
public class SampleCacheApplicationTests {
@Autowired
private CacheManager cacheManager;