HHH-7190 - Cache JDBC proxy class defintions

This commit is contained in:
Steve Ebersole 2012-03-22 09:04:44 -05:00
parent 624855c438
commit e24451637d
2 changed files with 249 additions and 51 deletions

View File

@ -0,0 +1,41 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.engine.jdbc.internal.proxy;
import org.hibernate.HibernateException;
/**
* Indicates a problem defining or instantiating a JDBC proxy class.
*
* @author Steve Ebersole
*/
public class JdbcProxyException extends HibernateException {
public JdbcProxyException(String message, Throwable root) {
super( message, root );
}
public JdbcProxyException(String message) {
super( message );
}
}

View File

@ -22,6 +22,9 @@
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.engine.jdbc.internal.proxy; package org.hibernate.engine.jdbc.internal.proxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.sql.CallableStatement; import java.sql.CallableStatement;
import java.sql.Connection; import java.sql.Connection;
@ -33,6 +36,7 @@ import java.sql.Statement;
import org.hibernate.engine.jdbc.spi.InvalidatableWrapper; import org.hibernate.engine.jdbc.spi.InvalidatableWrapper;
import org.hibernate.engine.jdbc.spi.JdbcWrapper; import org.hibernate.engine.jdbc.spi.JdbcWrapper;
import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor; import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
import org.hibernate.internal.util.Value;
/** /**
* Centralized builder for proxy instances * Centralized builder for proxy instances
@ -48,14 +52,37 @@ public class ProxyBuilder {
JdbcWrapper.class JdbcWrapper.class
}; };
public static Connection buildConnection(LogicalConnectionImplementor logicalConnection) { private static final Value<Constructor<Connection>> connectionProxyConstructorValue = new Value<Constructor<Connection>>(
ConnectionProxyHandler proxyHandler = new ConnectionProxyHandler( logicalConnection ); new Value.DeferredInitializer<Constructor<Connection>>() {
return ( Connection ) Proxy.newProxyInstance( @Override
public Constructor<Connection> initialize() {
try {
return locateConnectionProxyClass().getConstructor( InvocationHandler.class );
}
catch (NoSuchMethodException e) {
throw new JdbcProxyException( "Could not find proxy constructor in JDK generated Connection proxy class", e );
}
}
@SuppressWarnings("unchecked")
private Class<Connection> locateConnectionProxyClass() {
return (Class<Connection>) Proxy.getProxyClass(
JdbcWrapper.class.getClassLoader(), JdbcWrapper.class.getClassLoader(),
CONNECTION_PROXY_INTERFACES, CONNECTION_PROXY_INTERFACES
proxyHandler
); );
} }
}
);
public static Connection buildConnection(LogicalConnectionImplementor logicalConnection) {
final ConnectionProxyHandler proxyHandler = new ConnectionProxyHandler( logicalConnection );
try {
return connectionProxyConstructorValue.getValue().newInstance( proxyHandler );
}
catch (Exception e) {
throw new JdbcProxyException( "Could not instantiate JDBC Connection proxy", e );
}
}
// Statement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Statement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -66,20 +93,43 @@ public class ProxyBuilder {
InvalidatableWrapper.class InvalidatableWrapper.class
}; };
private static final Value<Constructor<Statement>> statementProxyConstructorValue = new Value<Constructor<Statement>>(
new Value.DeferredInitializer<Constructor<Statement>>() {
@Override
public Constructor<Statement> initialize() {
try {
return locateStatementProxyClass().getConstructor( InvocationHandler.class );
}
catch (NoSuchMethodException e) {
throw new JdbcProxyException( "Could not find proxy constructor in JDK generated Statement proxy class", e );
}
}
@SuppressWarnings("unchecked")
private Class<Statement> locateStatementProxyClass() {
return (Class<Statement>) Proxy.getProxyClass(
JdbcWrapper.class.getClassLoader(),
STMNT_PROXY_INTERFACES
);
}
}
);
public static Statement buildStatement( public static Statement buildStatement(
Statement statement, Statement statement,
ConnectionProxyHandler connectionProxyHandler, ConnectionProxyHandler connectionProxyHandler,
Connection connectionProxy) { Connection connectionProxy) {
BasicStatementProxyHandler proxyHandler = new BasicStatementProxyHandler( final BasicStatementProxyHandler proxyHandler = new BasicStatementProxyHandler(
statement, statement,
connectionProxyHandler, connectionProxyHandler,
connectionProxy connectionProxy
); );
return ( Statement ) Proxy.newProxyInstance( try {
JdbcWrapper.class.getClassLoader(), return statementProxyConstructorValue.getValue().newInstance( proxyHandler );
STMNT_PROXY_INTERFACES, }
proxyHandler catch (Exception e) {
); throw new JdbcProxyException( "Could not instantiate JDBC Statement proxy", e );
}
} }
public static Statement buildImplicitStatement( public static Statement buildImplicitStatement(
@ -89,12 +139,13 @@ public class ProxyBuilder {
if ( statement == null ) { if ( statement == null ) {
return null; return null;
} }
ImplicitStatementProxyHandler handler = new ImplicitStatementProxyHandler( statement, connectionProxyHandler, connectionProxy ); final ImplicitStatementProxyHandler proxyHandler = new ImplicitStatementProxyHandler( statement, connectionProxyHandler, connectionProxy );
return ( Statement ) Proxy.newProxyInstance( try {
JdbcWrapper.class.getClassLoader(), return statementProxyConstructorValue.getValue().newInstance( proxyHandler );
STMNT_PROXY_INTERFACES, }
handler catch (Exception e) {
); throw new JdbcProxyException( "Could not instantiate JDBC Statement proxy", e );
}
} }
@ -106,22 +157,45 @@ public class ProxyBuilder {
InvalidatableWrapper.class InvalidatableWrapper.class
}; };
private static final Value<Constructor<PreparedStatement>> preparedStatementProxyConstructorValue = new Value<Constructor<PreparedStatement>>(
new Value.DeferredInitializer<Constructor<PreparedStatement>>() {
@Override
public Constructor<PreparedStatement> initialize() {
try {
return locatePreparedStatementProxyClass().getConstructor( InvocationHandler.class );
}
catch (NoSuchMethodException e) {
throw new JdbcProxyException( "Could not find proxy constructor in JDK generated Statement proxy class", e );
}
}
@SuppressWarnings("unchecked")
private Class<PreparedStatement> locatePreparedStatementProxyClass() {
return (Class<PreparedStatement>) Proxy.getProxyClass(
JdbcWrapper.class.getClassLoader(),
PREPARED_STMNT_PROXY_INTERFACES
);
}
}
);
public static PreparedStatement buildPreparedStatement( public static PreparedStatement buildPreparedStatement(
String sql, String sql,
Statement statement, Statement statement,
ConnectionProxyHandler connectionProxyHandler, ConnectionProxyHandler connectionProxyHandler,
Connection connectionProxy) { Connection connectionProxy) {
PreparedStatementProxyHandler proxyHandler = new PreparedStatementProxyHandler( final PreparedStatementProxyHandler proxyHandler = new PreparedStatementProxyHandler(
sql, sql,
statement, statement,
connectionProxyHandler, connectionProxyHandler,
connectionProxy connectionProxy
); );
return ( PreparedStatement ) Proxy.newProxyInstance( try {
JdbcWrapper.class.getClassLoader(), return preparedStatementProxyConstructorValue.getValue().newInstance( proxyHandler );
PREPARED_STMNT_PROXY_INTERFACES, }
proxyHandler catch (Exception e) {
); throw new JdbcProxyException( "Could not instantiate JDBC PreparedStatement proxy", e );
}
} }
@ -133,22 +207,45 @@ public class ProxyBuilder {
InvalidatableWrapper.class InvalidatableWrapper.class
}; };
private static final Value<Constructor<CallableStatement>> callableStatementProxyConstructorValue = new Value<Constructor<CallableStatement>>(
new Value.DeferredInitializer<Constructor<CallableStatement>>() {
@Override
public Constructor<CallableStatement> initialize() {
try {
return locateCallableStatementProxyClass().getConstructor( InvocationHandler.class );
}
catch (NoSuchMethodException e) {
throw new JdbcProxyException( "Could not find proxy constructor in JDK generated Statement proxy class", e );
}
}
@SuppressWarnings("unchecked")
private Class<CallableStatement> locateCallableStatementProxyClass() {
return (Class<CallableStatement>) Proxy.getProxyClass(
JdbcWrapper.class.getClassLoader(),
CALLABLE_STMNT_PROXY_INTERFACES
);
}
}
);
public static CallableStatement buildCallableStatement( public static CallableStatement buildCallableStatement(
String sql, String sql,
CallableStatement statement, CallableStatement statement,
ConnectionProxyHandler connectionProxyHandler, ConnectionProxyHandler connectionProxyHandler,
Connection connectionProxy) { Connection connectionProxy) {
CallableStatementProxyHandler proxyHandler = new CallableStatementProxyHandler( final CallableStatementProxyHandler proxyHandler = new CallableStatementProxyHandler(
sql, sql,
statement, statement,
connectionProxyHandler, connectionProxyHandler,
connectionProxy connectionProxy
); );
return ( CallableStatement ) Proxy.newProxyInstance( try {
JdbcWrapper.class.getClassLoader(), return callableStatementProxyConstructorValue.getValue().newInstance( proxyHandler );
CALLABLE_STMNT_PROXY_INTERFACES, }
proxyHandler catch (Exception e) {
); throw new JdbcProxyException( "Could not instantiate JDBC CallableStatement proxy", e );
}
} }
@ -160,29 +257,56 @@ public class ProxyBuilder {
InvalidatableWrapper.class InvalidatableWrapper.class
}; };
private static final Value<Constructor<ResultSet>> resultSetProxyConstructorValue = new Value<Constructor<ResultSet>>(
new Value.DeferredInitializer<Constructor<ResultSet>>() {
@Override
public Constructor<ResultSet> initialize() {
try {
return locateCallableStatementProxyClass().getConstructor( InvocationHandler.class );
}
catch (NoSuchMethodException e) {
throw new JdbcProxyException( "Could not find proxy constructor in JDK generated ResultSet proxy class", e );
}
}
@SuppressWarnings("unchecked")
private Class<ResultSet> locateCallableStatementProxyClass() {
return (Class<ResultSet>) Proxy.getProxyClass(
JdbcWrapper.class.getClassLoader(),
RESULTSET_PROXY_INTERFACES
);
}
}
);
public static ResultSet buildResultSet( public static ResultSet buildResultSet(
ResultSet resultSet, ResultSet resultSet,
AbstractStatementProxyHandler statementProxyHandler, AbstractStatementProxyHandler statementProxyHandler,
Statement statementProxy) { Statement statementProxy) {
ResultSetProxyHandler proxyHandler = new ResultSetProxyHandler( resultSet, statementProxyHandler, statementProxy ); final ResultSetProxyHandler proxyHandler = new ResultSetProxyHandler( resultSet, statementProxyHandler, statementProxy );
return ( ResultSet ) Proxy.newProxyInstance( try {
JdbcWrapper.class.getClassLoader(), return resultSetProxyConstructorValue.getValue().newInstance( proxyHandler );
RESULTSET_PROXY_INTERFACES, }
proxyHandler catch (Exception e) {
); throw new JdbcProxyException( "Could not instantiate JDBC ResultSet proxy", e );
}
} }
public static ResultSet buildImplicitResultSet( public static ResultSet buildImplicitResultSet(
ResultSet resultSet, ResultSet resultSet,
ConnectionProxyHandler connectionProxyHandler, ConnectionProxyHandler connectionProxyHandler,
Connection connectionProxy) { Connection connectionProxy) {
ImplicitResultSetProxyHandler proxyHandler = new ImplicitResultSetProxyHandler( resultSet, connectionProxyHandler, connectionProxy ); final ImplicitResultSetProxyHandler proxyHandler = new ImplicitResultSetProxyHandler(
return ( ResultSet ) Proxy.newProxyInstance( resultSet,
JdbcWrapper.class.getClassLoader(), connectionProxyHandler,
RESULTSET_PROXY_INTERFACES, connectionProxy
proxyHandler
); );
try {
return resultSetProxyConstructorValue.getValue().newInstance( proxyHandler );
}
catch (Exception e) {
throw new JdbcProxyException( "Could not instantiate JDBC ResultSet proxy", e );
}
} }
public static ResultSet buildImplicitResultSet( public static ResultSet buildImplicitResultSet(
@ -190,12 +314,18 @@ public class ProxyBuilder {
ConnectionProxyHandler connectionProxyHandler, ConnectionProxyHandler connectionProxyHandler,
Connection connectionProxy, Connection connectionProxy,
Statement sourceStatement) { Statement sourceStatement) {
ImplicitResultSetProxyHandler proxyHandler = new ImplicitResultSetProxyHandler( resultSet, connectionProxyHandler, connectionProxy, sourceStatement ); final ImplicitResultSetProxyHandler proxyHandler = new ImplicitResultSetProxyHandler(
return ( ResultSet ) Proxy.newProxyInstance( resultSet,
JdbcWrapper.class.getClassLoader(), connectionProxyHandler,
RESULTSET_PROXY_INTERFACES, connectionProxy,
proxyHandler sourceStatement
); );
try {
return resultSetProxyConstructorValue.getValue().newInstance( proxyHandler );
}
catch (Exception e) {
throw new JdbcProxyException( "Could not instantiate JDBC ResultSet proxy", e );
}
} }
@ -206,15 +336,42 @@ public class ProxyBuilder {
JdbcWrapper.class JdbcWrapper.class
}; };
private static final Value<Constructor<DatabaseMetaData>> metadataProxyConstructorValue = new Value<Constructor<DatabaseMetaData>>(
new Value.DeferredInitializer<Constructor<DatabaseMetaData>>() {
@Override
public Constructor<DatabaseMetaData> initialize() {
try {
return locateDatabaseMetaDataProxyClass().getConstructor( InvocationHandler.class );
}
catch (NoSuchMethodException e) {
throw new JdbcProxyException( "Could not find proxy constructor in JDK generated DatabaseMetaData proxy class", e );
}
}
@SuppressWarnings("unchecked")
private Class<DatabaseMetaData> locateDatabaseMetaDataProxyClass() {
return (Class<DatabaseMetaData>) Proxy.getProxyClass(
JdbcWrapper.class.getClassLoader(),
METADATA_PROXY_INTERFACES
);
}
}
);
public static DatabaseMetaData buildDatabaseMetaData( public static DatabaseMetaData buildDatabaseMetaData(
DatabaseMetaData metaData, DatabaseMetaData metaData,
ConnectionProxyHandler connectionProxyHandler, ConnectionProxyHandler connectionProxyHandler,
Connection connectionProxy) { Connection connectionProxy) {
DatabaseMetaDataProxyHandler handler = new DatabaseMetaDataProxyHandler( metaData, connectionProxyHandler, connectionProxy ); final DatabaseMetaDataProxyHandler proxyHandler = new DatabaseMetaDataProxyHandler(
return ( DatabaseMetaData ) Proxy.newProxyInstance( metaData,
JdbcWrapper.class.getClassLoader(), connectionProxyHandler,
METADATA_PROXY_INTERFACES, connectionProxy
handler
); );
try {
return metadataProxyConstructorValue.getValue().newInstance( proxyHandler );
}
catch (Exception e) {
throw new JdbcProxyException( "Could not instantiate JDBC DatabaseMetaData proxy", e );
}
} }
} }