SpringのTransactionAwareDataSourceProxyとConnectionのプロキシ


DataSource、特にConnectionPoolDataSourceとXADataSourceまわりを色々調べていて、
JBoss、CommonsDBCP、C3P0とかみて、今日Springを見ていたら、ちょっと飛び道具的なコードに出会った.
Spring2.5.6/Spring3.0.0-M2にて確認.


普通のDataSourceを、Spring配下のトランザクションに組み込むためのTransactionAwareDataSourceProxyで、
getConnectionのところから実際にコネクションを返すコードが、以下のようになっていた.

	protected Connection getTransactionAwareConnectionProxy(DataSource targetDataSource) {
		return (Connection) Proxy.newProxyInstance(
				ConnectionProxy.class.getClassLoader(),
				new Class[] {ConnectionProxy.class},
				new TransactionAwareInvocationHandler(targetDataSource));
	}


最初???ってなったけど、TransactionAwareInvocationHandlerを見ると、DataSourceUtilsを呼びまくっていたので、
Connectionのラッパーを作るのではなくてプロキシにして、呼ばれたメソッドにあわせてDataSourceUtilsを呼びまくるところを
一カ所にまとめたのだなと理解.コードの記述は少なくなりますね、なるほど.
S2とかだと、ここはちゃんとラッパーつくってたと記憶しているので、このやり方もあるのかとやや驚き.
合点はいった。。。。が、なんか黒魔術的でびっくりしました.


しかし、昔から言われているDataSourceTransactionManagerとDataSourceUtilsのひどさって
まだ解消されてないんでしょうか...
JavaDocとか見ていると、透過的でないといけないと書いた直後に、DataSourceTransactionManagerのときは
あれこれしないといけませんて書いてあるのはちょっといただけないかと.

 * <p>Data access code that should remain unaware of Spring's data access support
 * can work with this proxy to seamlessly participate in Spring-managed transactions.
 * Note that the transaction manager, for example {@link DataSourceTransactionManager},
 * still needs to work with the underlying DataSource, <i>not</i> with this proxy.