1 16 17 package org.springframework.jdbc.datasource; 18 19 import java.lang.reflect.InvocationHandler ; 20 import java.lang.reflect.InvocationTargetException ; 21 import java.lang.reflect.Method ; 22 import java.lang.reflect.Proxy ; 23 import java.sql.Connection ; 24 import java.sql.SQLException ; 25 import java.sql.Statement ; 26 27 import javax.sql.DataSource ; 28 29 import org.springframework.util.Assert; 30 31 80 public class TransactionAwareDataSourceProxy extends DelegatingDataSource { 81 82 86 public TransactionAwareDataSourceProxy() { 87 } 88 89 93 public TransactionAwareDataSourceProxy(DataSource targetDataSource) { 94 super(targetDataSource); 95 } 96 97 98 107 public Connection getConnection() throws SQLException { 108 Assert.state(getTargetDataSource() != null, "'targetDataSource' is required"); 109 Connection con = DataSourceUtils.doGetConnection(getTargetDataSource()); 110 return getTransactionAwareConnectionProxy(con, getTargetDataSource()); 111 } 112 113 122 protected Connection getTransactionAwareConnectionProxy(Connection target, DataSource dataSource) { 123 return (Connection ) Proxy.newProxyInstance( 124 ConnectionProxy.class.getClassLoader(), 125 new Class [] {ConnectionProxy.class}, 126 new TransactionAwareInvocationHandler(target, dataSource)); 127 } 128 129 130 134 private static class TransactionAwareInvocationHandler implements InvocationHandler { 135 136 private final Connection target; 137 138 private final DataSource dataSource; 139 140 public TransactionAwareInvocationHandler(Connection target, DataSource dataSource) { 141 this.target = target; 142 this.dataSource = dataSource; 143 } 144 145 public Object invoke(Object proxy, Method method, Object [] args) throws Throwable { 146 148 if (method.getName().equals("getTargetConnection")) { 149 return this.target; 151 } 152 else if (method.getName().equals("equals")) { 153 return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE); 155 } 156 else if (method.getName().equals("hashCode")) { 157 return new Integer (hashCode()); 159 } 160 else if (method.getName().equals("close")) { 161 DataSourceUtils.doReleaseConnection(this.target, this.dataSource); 163 return null; 164 } 165 166 try { 168 Object retVal = method.invoke(this.target, args); 169 170 if (retVal instanceof Statement ) { 173 DataSourceUtils.applyTransactionTimeout((Statement ) retVal, this.dataSource); 174 } 175 176 return retVal; 177 } 178 catch (InvocationTargetException ex) { 179 throw ex.getTargetException(); 180 } 181 } 182 } 183 184 } 185 | Popular Tags |