Одним из основных принципов Spring является внедрение зависимостей . Spring основан на убеждении, что внедрение компонентов, которые класс использует в этот класс, приводит к тому, что код легче читается, легче тестируется и легче обслуживать, чем классы / код (например, ваш get()
метод) отвечает за поиск собственных зависимостей.
В качестве примера того, что это означает в более конкретных терминах: ваш метод get()
зависит как минимум от двух других классов: 1) «пула соединений» и 2) самого соединения. Метод get()
обладает глубокими знаниями , как он должен получить эти экземпляры.
В качестве альтернативы вашему стилю кодирования здесь, с подходом DI, класс, которому принадлежит ваш метод get()
, будет вставлять в него Connection
(или Datasource
) (через внедрение сеттера или конструктора).
Теперь, почему это простое изменение делает код проще и лучше?
Поскольку метод get()
больше не нуждается в деталях, которые не являются его основной обязанностью. Основная обязанность метода get()
заключается в том, чтобы узнать, как получить Agent
при Integer id
. Почему этому методу также нужно знать 1) откуда брать соединения и 2) что вы хотите объединять соединения?
Что происходит, когда вы хотите изменить логику подключения? Вам нужно прикоснуться к коду каждый и каждый метод доступа к данным в вашем приложении. Это было бы намного сложнее, чем нужно.
Это сила внедрения зависимости: она позволяет вам изменять детали (например, откуда происходит соединение JDBC) без необходимости также изменять код, который использует эти детали.
Что касается вашего фактического кода пула соединений, похоже, вы неправильно понимаете две концепции:
1) Ваш ConnectionPool
утверждает, что хочет быть Singleton, но вы предоставляете открытый конструктор, позволяющий соавторам по умолчанию полностью использовать единый экземпляр ConnectionPool
.
2) Ваш пул соединений на самом деле не является пулом соединений! Идея пула соединений состоит в том, чтобы открыть N соединений с базой данных, а затем раздать каждое из этих N соединений коду, который требует соединения по требованию. Основная идея здесь заключается в том, что вы можете перерабатывать соединения и избегать дорогостоящих затрат на открытие нового соединения для каждого запроса. В пуле соединений, когда код, использующий соединение, выполняется с его соединением, физическое соединение фактически не прерывается - вместо этого дескриптор соединения просто возвращается в пул для повторного использования другим запросом / потоком / методом.
Самое главное, что в приложениях, использующих пул соединений, код, отвечающий за доступ к данным, обычно даже не знает, что его соединения объединяются - вместо этого DAO просто имеет ссылку на DataSource
Интерфейс и DAO понятия не имеют, что на самом деле происходит, когда он запрашивает соединение DataSource
, или что происходит, когда соединение освобождается. Таким образом, вы можете абстрагироваться от деталей «как мне соединиться» из кода, отвечающего за логику высшего порядка, такого как «как мне получить агента из этого целого числа?». Эта абстракция - это то, что позволяет вам изменять один слой вашего приложения, не переписывая все остальные слои - вы разъединили слои, и каждый заботится только о том, за что он действительно отвечает.
Я настоятельно рекомендую вам прочесть не только идею пула соединений, но и Внедрение зависимостей .Почему в мире вы используете Spring без компонентов DI?Что касается пулов соединений, зачем тратить время на переизобретение колеса, написав свою собственную, вместо использования ряда уже существующих и популярных библиотек, таких как commons-dbcp или c3p0 ?Вместо того, чтобы заново изобретать колесо, используйте существующую библиотеку (в которой меньше ошибок, чем в вашем домашнем решении), и сосредоточьтесь на создании реального приложения.