想在新项目中使用mybatis,于是这几天在看官方问题。
发现mytatis3中自带的连接池,不知道性能如何?
配置了连接池,为了验证连接池返回的连接是否是同一个连接
把poolMaximumActiveConnections这个属性配置为1,那么连接池中最多只有一个活跃连接了
然后用以下代码验证:
while (true) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
if (str.equals("bye")) {
break;
}
SqlSession session = sqlSessionFactory.openSession();
System.out.println(System.identityHashCode(session.getConnection()));
session.close();
}
但是方法,每次输出的值都不一样。疑惑。。。
于是跟踪源代码,发现
通过session.getConnection()这个方法返回的connection对象其实并不是原始的connection
而是个代理对象proxyConnection,它动态代理了那个原始Connection对象realConnection,为的是拦截realConnection的close方法
因为连接池中的连接并不应该去关闭,当调用close方法的时候应该是将此连接放回连接池的空闲队列中。
源码如下:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
if (CLOSE.hashCode() == methodName.hashCode() && CLOSE.equals(methodName)) {
dataSource.pushConnection(this);
return null;
} else {
try {
if (!Object.class.equals(method.getDeclaringClass())) {
// issue #579 toString() should never fail
// throw an SQLException instead of a Runtime
checkConnection();
}
return method.invoke(realConnection, args);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}
}
之后通过调试发现realConnection每次都是同一个,终于验证了想法!
另外:我发现PooledDataSource,也就是使用连接池的数据源其实内部持有了一个UnpooledDataSource的对象
基础的数据源操作(getConnection)和属性(username, password, url........)都在UnpooledDataSource中定义了
PooledDataSource只负责自己那块连接池的逻辑,其余的都交给UnpooledDataSource来处理