diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/LoggingCacheErrorHandler.java b/spring-context/src/main/java/org/springframework/cache/interceptor/LoggingCacheErrorHandler.java
index d13a1cb8e2c..bfb821e350d 100644
--- a/spring-context/src/main/java/org/springframework/cache/interceptor/LoggingCacheErrorHandler.java
+++ b/spring-context/src/main/java/org/springframework/cache/interceptor/LoggingCacheErrorHandler.java
@@ -16,6 +16,8 @@
package org.springframework.cache.interceptor;
+import java.util.function.Supplier;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -78,47 +80,71 @@ public class LoggingCacheErrorHandler implements CacheErrorHandler {
@Override
public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
- logCacheError(logger,
- createMessage(cache, "failed to get entry with key '" + key + "'"),
+ logCacheError(
+ () -> String.format("Cache '%s' failed to get entry with key '%s'", cache.getName(), key),
exception);
}
@Override
public void handleCachePutError(RuntimeException exception, Cache cache, Object key, @Nullable Object value) {
- logCacheError(logger,
- createMessage(cache, "failed to put entry with key '" + key + "'"),
+ logCacheError(
+ () -> String.format("Cache '%s' failed to put entry with key '%s'", cache.getName(), key),
exception);
}
@Override
public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
- logCacheError(logger,
- createMessage(cache, "failed to evict entry with key '" + key + "'"),
+ logCacheError(
+ () -> String.format("Cache '%s' failed to evict entry with key '%s'", cache.getName(), key),
exception);
}
@Override
public void handleCacheClearError(RuntimeException exception, Cache cache) {
- logCacheError(logger, createMessage(cache, "failed to clear entries"), exception);
+ logCacheError(
+ () -> String.format("Cache '%s' failed to clear entries", cache.getName()),
+ exception);
}
+
/**
- * Log the specified message.
- * @param logger the logger
- * @param message the message
- * @param ex the exception
+ * Get the logger for this {@code LoggingCacheErrorHandler}.
+ * @return the logger
+ * @since 5.3.22
*/
- protected void logCacheError(Log logger, String message, RuntimeException ex) {
- if (this.logStackTraces) {
- logger.warn(message, ex);
- }
- else {
- logger.warn(message);
- }
+ protected final Log getLogger() {
+ return logger;
}
- private String createMessage(Cache cache, String reason) {
- return String.format("Cache '%s' %s", cache.getName(), reason);
+ /**
+ * Get the {@code logStackTraces} flag for this {@code LoggingCacheErrorHandler}.
+ * @return {@code true} if this {@code LoggingCacheErrorHandler} logs stack traces
+ * @since 5.3.22
+ */
+ protected final boolean isLogStackTraces() {
+ return this.logStackTraces;
+ }
+
+ /**
+ * Log the cache error message in the given supplier.
+ *
If {@link #isLogStackTraces()} is {@code true}, the given
+ * {@code exception} will be logged as well.
+ *
The default implementation logs the message as a warning.
+ * @param messageSupplier the message supplier
+ * @param exception the exception thrown by the cache provider
+ * @since 5.3.22
+ * @see #isLogStackTraces()
+ * @see #getLogger()
+ */
+ protected void logCacheError(Supplier messageSupplier, RuntimeException exception) {
+ if (getLogger().isWarnEnabled()) {
+ if (isLogStackTraces()) {
+ getLogger().warn(messageSupplier.get(), exception);
+ }
+ else {
+ getLogger().warn(messageSupplier.get());
+ }
+ }
}
}
diff --git a/spring-context/src/test/java/org/springframework/cache/interceptor/LoggingCacheErrorHandlerTests.java b/spring-context/src/test/java/org/springframework/cache/interceptor/LoggingCacheErrorHandlerTests.java
index d07ed63fb0e..e9dc0641694 100644
--- a/spring-context/src/test/java/org/springframework/cache/interceptor/LoggingCacheErrorHandlerTests.java
+++ b/spring-context/src/test/java/org/springframework/cache/interceptor/LoggingCacheErrorHandlerTests.java
@@ -17,13 +17,14 @@
package org.springframework.cache.interceptor;
import org.apache.commons.logging.Log;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.cache.Cache;
import org.springframework.cache.support.NoOpCache;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
@@ -32,48 +33,55 @@ import static org.mockito.Mockito.verify;
* @author Adam Ostrožlík
* @author Stephane Nicoll
* @author Vedran Pavic
+ * @author Sam Brannen
*/
-@ExtendWith(MockitoExtension.class)
class LoggingCacheErrorHandlerTests {
- @Mock
- private Log logger;
+ private static final Cache CACHE = new NoOpCache("NOOP");
+
+ private static final String KEY = "enigma";
+
+ private final Log logger = mock(Log.class);
+
+ private LoggingCacheErrorHandler handler = new LoggingCacheErrorHandler(this.logger, false);
+
+
+ @BeforeEach
+ void setUp() {
+ given(this.logger.isWarnEnabled()).willReturn(true);
+ }
@Test
void handleGetCacheErrorLogsAppropriateMessage() {
- LoggingCacheErrorHandler handler = new LoggingCacheErrorHandler(this.logger, false);
- handler.handleCacheGetError(new RuntimeException(), new NoOpCache("NOOP"), "key");
- verify(this.logger).warn("Cache 'NOOP' failed to get entry with key 'key'");
+ this.handler.handleCacheGetError(new RuntimeException(), CACHE, KEY);
+ verify(this.logger).warn("Cache 'NOOP' failed to get entry with key 'enigma'");
}
@Test
void handlePutCacheErrorLogsAppropriateMessage() {
- LoggingCacheErrorHandler handler = new LoggingCacheErrorHandler(this.logger, false);
- handler.handleCachePutError(new RuntimeException(), new NoOpCache("NOOP"), "key", new Object());
- verify(this.logger).warn("Cache 'NOOP' failed to put entry with key 'key'");
+ this.handler.handleCachePutError(new RuntimeException(), CACHE, KEY, null);
+ verify(this.logger).warn("Cache 'NOOP' failed to put entry with key 'enigma'");
}
@Test
void handleEvictCacheErrorLogsAppropriateMessage() {
- LoggingCacheErrorHandler handler = new LoggingCacheErrorHandler(this.logger, false);
- handler.handleCacheEvictError(new RuntimeException(), new NoOpCache("NOOP"), "key");
- verify(this.logger).warn("Cache 'NOOP' failed to evict entry with key 'key'");
+ this.handler.handleCacheEvictError(new RuntimeException(), CACHE, KEY);
+ verify(this.logger).warn("Cache 'NOOP' failed to evict entry with key 'enigma'");
}
@Test
void handleClearErrorLogsAppropriateMessage() {
- LoggingCacheErrorHandler handler = new LoggingCacheErrorHandler(this.logger, false);
- handler.handleCacheClearError(new RuntimeException(), new NoOpCache("NOOP"));
+ this.handler.handleCacheClearError(new RuntimeException(), CACHE);
verify(this.logger).warn("Cache 'NOOP' failed to clear entries");
}
@Test
- void handleCacheErrorWithStacktrace() {
- LoggingCacheErrorHandler handler = new LoggingCacheErrorHandler(this.logger, true);
+ void handleGetCacheErrorWithStackTraceLoggingEnabled() {
+ this.handler = new LoggingCacheErrorHandler(this.logger, true);
RuntimeException exception = new RuntimeException();
- handler.handleCacheGetError(exception, new NoOpCache("NOOP"), "key");
- verify(this.logger).warn("Cache 'NOOP' failed to get entry with key 'key'", exception);
+ this.handler.handleCacheGetError(exception, CACHE, KEY);
+ verify(this.logger).warn("Cache 'NOOP' failed to get entry with key 'enigma'", exception);
}
}