package utils; import java.lang.reflect.Proxy; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public final class ConnectionManager { private static final String DB_URL_KEY = "db.url"; private static final String DB_USER_KEY = "db.user"; private static final String DB_PASSWORD_KEY = "db.password"; private static final String DB_POOL_SIZE_KEY = "db.pool.size"; private static final int DEFAULT_POOL_SIZE = 10; private static BlockingQueue pool; static { loadDriver(); initConnectionPool(); } private static void loadDriver() { try { Class.forName("org.postgresql.Driver"); Class.forName("utils.UrlPath"); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } private static void initConnectionPool() { String poolSize = PropertiesUtil.get(DB_POOL_SIZE_KEY); int size = poolSize == null ? DEFAULT_POOL_SIZE : Integer.parseInt(poolSize); pool = new ArrayBlockingQueue<>(size); for (int i = 0; i < size; i++) { Connection connection = open(); var proxyConnection = (Connection) Proxy.newProxyInstance(ConnectionManager.class.getClassLoader(), new Class[]{Connection.class}, (proxy, method, args) -> method.getName().equals("close") ? pool.add((Connection) proxy) : method.invoke(connection, args) ); pool.add(proxyConnection); } } public static Connection get() { try { return pool.take(); } catch (InterruptedException e) { throw new RuntimeException(e); } } private static Connection open() { try { return DriverManager.getConnection(PropertiesUtil.get(DB_URL_KEY), PropertiesUtil.get(DB_USER_KEY), PropertiesUtil.get(DB_PASSWORD_KEY)); } catch (SQLException e) { throw new RuntimeException(e); } } private ConnectionManager() { } }