diff --git a/jOOQ/src/main/java/org/jooq/impl/Util.java b/jOOQ/src/main/java/org/jooq/impl/Util.java index ec9b388136..2cb607ee39 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Util.java +++ b/jOOQ/src/main/java/org/jooq/impl/Util.java @@ -54,6 +54,8 @@ import java.sql.Statement; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import javax.persistence.Column; import javax.persistence.Entity; @@ -94,13 +96,18 @@ final class Util { * The default escape character for [a] LIKE [b] ESCAPE [...] * clauses. */ - static final char ESCAPE = '!'; + static final char ESCAPE = '!'; /** * Indicating whether JPA (javax.persistence) is on the * classpath. */ - private static Boolean isJPAAvailable; + private static Boolean isJPAAvailable; + + /** + * A cache for {@link ExecuteListener} classes + */ + private static final Map> EXECUTE_LISTENERS = new ConcurrentHashMap>(); /** * Create a new Oracle-style VARRAY {@link ArrayRecord} @@ -842,18 +849,28 @@ final class Util { } for (String listener : configuration.getSettings().getExecuteListeners()) { - try { - // [#1170] TODO: Cache these classes? - result.add((ExecuteListener) Class.forName(listener).newInstance()); - } - catch (Exception e) { - throw new RuntimeException(e); - } + result.add(getListener(listener)); } return result; } + private static final ExecuteListener getListener(String name) { + try { + Class type = EXECUTE_LISTENERS.get(name); + + if (type == null) { + type = Class.forName(name); + EXECUTE_LISTENERS.put(name, type); + } + + return (ExecuteListener) type.newInstance(); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + /** * Wrap a piece of SQL code in parentheses, if not wrapped already */