added limit for parsed SQL cache to NamedParameterJdbcTemplate (SPR-7237); added configurable cache limit to CachingMetadataReaderFactory
This commit is contained in:
parent
b4af04ba9d
commit
2136b04b65
|
|
@ -34,9 +34,19 @@ import org.springframework.core.io.ResourceLoader;
|
||||||
*/
|
*/
|
||||||
public class CachingMetadataReaderFactory extends SimpleMetadataReaderFactory {
|
public class CachingMetadataReaderFactory extends SimpleMetadataReaderFactory {
|
||||||
|
|
||||||
private static final int MAX_ENTRIES = 256;
|
/** Default maximum number of entries for the MetadataReader cache: 256 */
|
||||||
|
public static final int DEFAULT_CACHE_LIMIT = 256;
|
||||||
|
|
||||||
private final Map<Resource, MetadataReader> classReaderCache = createLRUCache();
|
|
||||||
|
private volatile int cacheLimit = DEFAULT_CACHE_LIMIT;
|
||||||
|
|
||||||
|
private final Map<Resource, MetadataReader> classReaderCache =
|
||||||
|
new LinkedHashMap<Resource, MetadataReader>(DEFAULT_CACHE_LIMIT, 0.75f, true) {
|
||||||
|
@Override
|
||||||
|
protected boolean removeEldestEntry(Map.Entry<Resource, MetadataReader> eldest) {
|
||||||
|
return size() > getCacheLimit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -64,8 +74,27 @@ public class CachingMetadataReaderFactory extends SimpleMetadataReaderFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the maximum number of entries for the MetadataReader cache.
|
||||||
|
* Default is 256.
|
||||||
|
*/
|
||||||
|
public void setCacheLimit(int cacheLimit) {
|
||||||
|
this.cacheLimit = cacheLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the maximum number of entries for the MetadataReader cache.
|
||||||
|
*/
|
||||||
|
public int getCacheLimit() {
|
||||||
|
return this.cacheLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MetadataReader getMetadataReader(Resource resource) throws IOException {
|
public MetadataReader getMetadataReader(Resource resource) throws IOException {
|
||||||
|
if (getCacheLimit() <= 0) {
|
||||||
|
return super.getMetadataReader(resource);
|
||||||
|
}
|
||||||
synchronized (this.classReaderCache) {
|
synchronized (this.classReaderCache) {
|
||||||
MetadataReader metadataReader = this.classReaderCache.get(resource);
|
MetadataReader metadataReader = this.classReaderCache.get(resource);
|
||||||
if (metadataReader == null) {
|
if (metadataReader == null) {
|
||||||
|
|
@ -76,15 +105,4 @@ public class CachingMetadataReaderFactory extends SimpleMetadataReaderFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
private static <K, V> Map<K, V> createLRUCache() {
|
|
||||||
return new LinkedHashMap<K, V>(MAX_ENTRIES, 0.75f, true) {
|
|
||||||
@Override
|
|
||||||
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
|
|
||||||
return size() > MAX_ENTRIES;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2010 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.
|
||||||
|
|
@ -16,10 +16,9 @@
|
||||||
|
|
||||||
package org.springframework.jdbc.core.namedparam;
|
package org.springframework.jdbc.core.namedparam;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
|
|
@ -60,11 +59,23 @@ import org.springframework.util.Assert;
|
||||||
*/
|
*/
|
||||||
public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations {
|
public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations {
|
||||||
|
|
||||||
|
/** Default maximum number of entries for this template's SQL cache: 256 */
|
||||||
|
public static final int DEFAULT_CACHE_LIMIT = 256;
|
||||||
|
|
||||||
|
|
||||||
/** The JdbcTemplate we are wrapping */
|
/** The JdbcTemplate we are wrapping */
|
||||||
private final JdbcOperations classicJdbcTemplate;
|
private final JdbcOperations classicJdbcTemplate;
|
||||||
|
|
||||||
/** Map of original SQL String to ParsedSql representation */
|
private volatile int cacheLimit = DEFAULT_CACHE_LIMIT;
|
||||||
private final Map<String, ParsedSql> parsedSqlCache = new HashMap<String, ParsedSql>();
|
|
||||||
|
/** Cache of original SQL String to ParsedSql representation */
|
||||||
|
private final Map<String, ParsedSql> parsedSqlCache =
|
||||||
|
new LinkedHashMap<String, ParsedSql>(DEFAULT_CACHE_LIMIT, 0.75f, true) {
|
||||||
|
@Override
|
||||||
|
protected boolean removeEldestEntry(Map.Entry<String, ParsedSql> eldest) {
|
||||||
|
return size() > getCacheLimit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -73,7 +84,7 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
|
||||||
* @param dataSource the JDBC DataSource to access
|
* @param dataSource the JDBC DataSource to access
|
||||||
*/
|
*/
|
||||||
public NamedParameterJdbcTemplate(DataSource dataSource) {
|
public NamedParameterJdbcTemplate(DataSource dataSource) {
|
||||||
Assert.notNull(dataSource, "The [dataSource] argument cannot be null.");
|
Assert.notNull(dataSource, "DataSource must not be null");
|
||||||
this.classicJdbcTemplate = new JdbcTemplate(dataSource);
|
this.classicJdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,6 +107,21 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
|
||||||
return this.classicJdbcTemplate;
|
return this.classicJdbcTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the maximum number of entries for this template's SQL cache.
|
||||||
|
* Default is 256.
|
||||||
|
*/
|
||||||
|
public void setCacheLimit(int cacheLimit) {
|
||||||
|
this.cacheLimit = cacheLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the maximum number of entries for this template's SQL cache.
|
||||||
|
*/
|
||||||
|
public int getCacheLimit() {
|
||||||
|
return this.cacheLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public <T> T execute(String sql, SqlParameterSource paramSource, PreparedStatementCallback<T> action)
|
public <T> T execute(String sql, SqlParameterSource paramSource, PreparedStatementCallback<T> action)
|
||||||
throws DataAccessException {
|
throws DataAccessException {
|
||||||
|
|
@ -294,10 +320,15 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain a parsed representation of the given SQL statement.
|
* Obtain a parsed representation of the given SQL statement.
|
||||||
|
* <p>The default implementation uses an LRU cache with an upper limit
|
||||||
|
* of 256 entries.
|
||||||
* @param sql the original SQL
|
* @param sql the original SQL
|
||||||
* @return a representation of the parsed SQL statement
|
* @return a representation of the parsed SQL statement
|
||||||
*/
|
*/
|
||||||
protected ParsedSql getParsedSql(String sql) {
|
protected ParsedSql getParsedSql(String sql) {
|
||||||
|
if (getCacheLimit() <= 0) {
|
||||||
|
return NamedParameterUtils.parseSqlStatement(sql);
|
||||||
|
}
|
||||||
synchronized (this.parsedSqlCache) {
|
synchronized (this.parsedSqlCache) {
|
||||||
ParsedSql parsedSql = this.parsedSqlCache.get(sql);
|
ParsedSql parsedSql = this.parsedSqlCache.get(sql);
|
||||||
if (parsedSql == null) {
|
if (parsedSql == null) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue