【发布时间】:2021-06-06 12:19:31
【问题描述】:
我有一个 Java/Spring/Hibernate 项目,该项目与 Vertica DB 有连接。有时,由于某些环境问题,连接会中断,我正在尝试在运行时重新建立连接。问题是原始连接,即@Autowired into repositories 没有得到更新,并且仍然指向原始的“死”连接。
在服务器启动期间,原始连接通过配置创建为@Bean。
配置:
package com.myproject.configs
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import lombok.extern.slf4j.Slf4j;
@Configuration
@Slf4j
public class dbConfig {
@Value("${db.jdbcUrl}")
private String connectionString;
@Value("${db.username}")
private String username;
@Value("${db.password}")
private String password;
@Bean(name = "dbConnection", destroyMethod = "close")
public Connection dbConn() throws SQLException {
Properties myProp = new Properties();
myProp.put("user", username);
myProp.put("password", password);
Connection conn;
try {
conn = DriverManager.getConnection(connectionString, myProp);
return conn;
} catch (SQLException e) {
log.error("Cannot establish DB connection");
throw e;
}
}
}
用法:
@Repository
@Slf4j
public class SomeDbRepository {
@Autowired
Connection dbConnection;
...
现在,我需要监控传入的 API 请求是否真的会到达数据库,所以我想检查拦截器中的所有传入请求,然后如果连接没有响应,则重新建立它。
所以,我使用上下文来获取 bean 并再次运行 dbConn():
package com.myproject.interceptors;
import com.myproject.configs.DbConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.*;
@Component
@Slf4j
public class DbConnectionCheckInterceptor extends HandlerInterceptorAdapter {
@Autowired
Connection dbConnection;
@Autowired
ApplicationContext context;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
try {
Statement stmt = dbConnection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT 1;");
rs.next();
return true;
} catch (SQLException e) {
try {
DbConfig dbConfig = context.getBean(DbConfig.class);
// *** here i am trying to re-establish the connection by accessing the bean through context ***
dbConfig.dbConn();
return true;
} catch (Exception ex) {
log.error("Couldn't connect to DB", ex);
return false;
}
}
}
}
任何想法都会受到赞赏。谢谢。
【问题讨论】:
-
如果你需要刷新这个连接,你可以取消Using spring bean,也许你可以使用静态方法来获取连接对象(而不是bean),它有你的重新连接逻辑(如果required) 否则返回预填充的数据库连接对象。
标签: java spring runtime database-connection autowired