Introduce reset() method in ContextCache

This commit is contained in:
Sam Brannen 2015-04-17 22:51:04 +02:00
parent c29eae3307
commit 2a4f4cd258
4 changed files with 44 additions and 27 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -31,16 +31,18 @@ import org.springframework.test.annotation.DirtiesContext.HierarchyMode;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* Cache for Spring {@link ApplicationContext ApplicationContexts} in a test environment. * Cache for Spring {@link ApplicationContext ApplicationContexts} in a test
* environment.
* *
* <p>Maintains a cache of {@code ApplicationContexts} keyed by * <p>{@code ContextCache} maintains a cache of {@code ApplicationContexts}
* {@link MergedContextConfiguration} instances. * keyed by {@link MergedContextConfiguration} instances.
* *
* <p>This has significant performance benefits if initializing the context would take time. * <p>Caching has significant performance benefits if initializing the context
* While initializing a Spring context itself is very quick, some beans in a context, such * takes a considerable about of time. Although initializing a Spring context
* as a {@code LocalSessionFactoryBean} for working with Hibernate, may take some time to * itself is very quick, some beans in a context, such as a
* initialize. Hence it often makes sense to perform that initialization only once per * {@code LocalSessionFactoryBean} for working with Hibernate, may take some
* test suite. * time to initialize. Hence it often makes sense to perform that initialization
* only once per test suite.
* *
* @author Sam Brannen * @author Sam Brannen
* @author Juergen Hoeller * @author Juergen Hoeller
@ -67,21 +69,36 @@ class ContextCache {
private final AtomicInteger missCount = new AtomicInteger(); private final AtomicInteger missCount = new AtomicInteger();
/**
* Reset all state maintained by this cache.
* @see #clear()
* @see #clearStatistics()
*/
public void reset() {
synchronized (contextMap) {
clear();
clearStatistics();
}
}
/** /**
* Clear all contexts from the cache and clear context hierarchy information as well. * Clear all contexts from the cache and clear context hierarchy information as well.
*/ */
public void clear() { public void clear() {
this.contextMap.clear(); synchronized (contextMap) {
this.hierarchyMap.clear(); this.contextMap.clear();
this.hierarchyMap.clear();
}
} }
/** /**
* Clear hit and miss count statistics for the cache (i.e., reset counters to zero). * Clear hit and miss count statistics for the cache (i.e., reset counters to zero).
*/ */
public void clearStatistics() { public void clearStatistics() {
this.hitCount.set(0); synchronized (contextMap) {
this.missCount.set(0); this.hitCount.set(0);
this.missCount.set(0);
}
} }
/** /**
@ -117,8 +134,8 @@ class ContextCache {
/** /**
* Get the overall hit count for this cache. * Get the overall hit count for this cache.
* <p>A <em>hit</em> is an access to the cache, which returned a non-null context * <p>A <em>hit</em> is any access to the cache that returns a non-null
* for a queried key. * context for the queried key.
*/ */
public int getHitCount() { public int getHitCount() {
return this.hitCount.get(); return this.hitCount.get();
@ -126,15 +143,16 @@ class ContextCache {
/** /**
* Get the overall miss count for this cache. * Get the overall miss count for this cache.
* <p>A <em>miss</em> is an access to the cache, which returned a {@code null} context * <p>A <em>miss</em> is any access to the cache that returns a {@code null}
* for a queried key. * context for the queried key.
*/ */
public int getMissCount() { public int getMissCount() {
return this.missCount.get(); return this.missCount.get();
} }
/** /**
* Explicitly add an {@code ApplicationContext} instance to the cache under the given key. * Explicitly add an {@code ApplicationContext} instance to the cache
* under the given key.
* @param key the context key (never {@code null}) * @param key the context key (never {@code null})
* @param context the {@code ApplicationContext} instance (never {@code null}) * @param context the {@code ApplicationContext} instance (never {@code null})
*/ */
@ -240,9 +258,11 @@ class ContextCache {
} }
/** /**
* Generate a text string, which contains the {@linkplain #size} as well * Generate a text string containing the statistics for this cache.
* as the {@linkplain #getHitCount() hit}, {@linkplain #getMissCount() miss}, * <p>Specifically, the returned string contains the {@linkplain #size},
* and {@linkplain #getParentContextCount() parent context} counts. * {@linkplain #getHitCount() hit count}, {@linkplain #getMissCount() miss count},
* and {@linkplain #getParentContextCount() parent context count}.
* @return the statistics for this cache
*/ */
@Override @Override
public String toString() { public String toString() {

View File

@ -80,8 +80,7 @@ public class ClassLevelDirtiesContextTestNGTests {
@BeforeClass @BeforeClass
public static void verifyInitialCacheState() { public static void verifyInitialCacheState() {
ContextCache contextCache = TestContextManager.contextCache; ContextCache contextCache = TestContextManager.contextCache;
contextCache.clear(); contextCache.reset();
contextCache.clearStatistics();
cacheHits.set(0); cacheHits.set(0);
cacheMisses.set(0); cacheMisses.set(0);
assertContextCacheStatistics("BeforeClass", 0, cacheHits.get(), cacheMisses.get()); assertContextCacheStatistics("BeforeClass", 0, cacheHits.get(), cacheMisses.get());

View File

@ -75,8 +75,7 @@ public class ClassLevelDirtiesContextTests {
@BeforeClass @BeforeClass
public static void verifyInitialCacheState() { public static void verifyInitialCacheState() {
ContextCache contextCache = TestContextManager.contextCache; ContextCache contextCache = TestContextManager.contextCache;
contextCache.clear(); contextCache.reset();
contextCache.clearStatistics();
cacheHits.set(0); cacheHits.set(0);
cacheMisses.set(0); cacheMisses.set(0);
assertContextCacheStatistics("BeforeClass", 0, cacheHits.get(), cacheMisses.get()); assertContextCacheStatistics("BeforeClass", 0, cacheHits.get(), cacheMisses.get());

View File

@ -59,8 +59,7 @@ public class SpringRunnerContextCacheTests {
public static void verifyInitialCacheState() { public static void verifyInitialCacheState() {
dirtiedApplicationContext = null; dirtiedApplicationContext = null;
ContextCache contextCache = TestContextManager.contextCache; ContextCache contextCache = TestContextManager.contextCache;
contextCache.clear(); contextCache.reset();
contextCache.clearStatistics();
assertContextCacheStatistics("BeforeClass", 0, 0, 0); assertContextCacheStatistics("BeforeClass", 0, 0, 0);
} }