如何从Spring Bean获取的DataSource/Connection提取Login对象创建DatabaseSession?
Great question! Let's walk through your options here—since you're working with Spring-managed connections and data sources, there are a few practical approaches to solve this.
Can you extract a Login object directly from an existing Connection?
Short answer: Probably not reliably.
JDBC Connection objects typically don't expose full login credentials (especially passwords) for security reasons. While you might be able to get the username via connection.getMetaData().getUserName(), most JDBC drivers will return null or an empty string for connection.getPassword()—it's not part of the standard metadata retained after the connection is established. So extracting a complete Login object directly from the connection itself is unlikely to work.
Alternative Solutions
Here are the most straightforward workarounds tailored to your Spring environment:
1. Pull login credentials directly from your Spring configuration or DataSource
Since your DataSource is managed by Spring, the login credentials (username/password) are almost certainly defined in your application config (like application.properties or application.yml). You can inject these directly, or access them from the DataSource implementation if it exposes them:
@Autowired private DataSource dataSource; @Value("${spring.datasource.username}") private String dbUsername; @Value("${spring.datasource.password}") private String dbPassword; public void initializeDatabaseSession() { // Option 1: Use injected config values Login login = new Login(dbUsername, dbPassword); // Option 2: Access from DataSource (if your implementation supports it, e.g., HikariCP) // if (dataSource instanceof HikariDataSource hikariDs) { // Login login = new Login(hikariDs.getUsername(), hikariDs.getPassword()); // } Project.SetLogin(login); DatabaseSession session = Project.createDatabaseSession(); }
Note: If you're using encrypted credentials in your config (e.g., with Jasypt), make sure your Spring setup can decrypt them before injecting.
2. Create a custom DataSource wrapper to retain login details
If you want a more reusable, decoupled approach, wrap your Spring-managed DataSource to store the login credentials at initialization time:
@Component public class LoginTrackingDataSource implements DataSource { private final DataSource delegateDataSource; private final Login login; // Inject credentials and the original DataSource public LoginTrackingDataSource(@Value("${spring.datasource.username}") String username, @Value("${spring.datasource.password}") String password, @Autowired DataSource delegateDataSource) { this.login = new Login(username, password); this.delegateDataSource = delegateDataSource; } // Delegate all DataSource methods to the original instance @Override public Connection getConnection() throws SQLException { return delegateDataSource.getConnection(); } @Override public Connection getConnection(String username, String password) throws SQLException { return delegateDataSource.getConnection(username, password); } // Implement remaining DataSource methods (isWrapperFor, unwrap, getLogWriter, etc.) // ... // Expose the stored Login object public Login getLogin() { return login; } }
Then inject this wrapper wherever you need to get the Login object:
@Autowired private LoginTrackingDataSource loginAwareDataSource; public void setupSession() { Login login = loginAwareDataSource.getLogin(); Project.SetLogin(login); DatabaseSession session = Project.createDatabaseSession(); }
3. Check if Project supports direct Connection/DataSource usage
Before jumping through hoops with Login objects, check if the Project class has an overloaded createDatabaseSession method that accepts a Connection or DataSource directly. If it does, you can skip setting the login entirely and use your existing Spring-managed connection:
@Autowired private Connection connection; // Or inject DataSource and get connection from it public void createSessionDirectly() { // If this method exists, it's the simplest solution DatabaseSession session = Project.createDatabaseSession(connection); }
This is the cleanest approach if the API supports it—no need to mess with login credentials at all.
内容的提问来源于stack exchange,提问作者alpino

