As far as obtaining a Connection, it depends on the implementation of the DataSource interface. An implementation might create a new Connection instance for every invocation of getconnection(), or it may be backed by a pool of Connection objects. The former would be on-par with how a Connection is created by the DriverManager class. The latter would be more efficient as Connections are reused instead of recreated over and over. This approach is very commonly used by applications deployed in servlet containers / application servers.
Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.