在 Java 和 MySQL 中,我们希望添加 jdbc ClientInfo 来标识每个查询的来源。目前我们可以做这样的事情:
try(Connection connection = dataSource.getConnection()){
connection.setClientInfo("ApplicationName", "MyApp");
}
但是我需要将其添加到创建的每个连接中,这意味着检查所有源代码以查找创建新连接的位置。我想将其设置为数据源级别。
到目前为止,对我有用的是使用调用 setClientInfo 的自定义重写 getConnection 方法来扩展 DataSource。这不仅是一个肮脏的解决方法,而且是特定于数据源的。
我看到mysql驱动程序有ClientInfoProviders,就像默认的com.mysql.cj.jdbc.CommentClientInfoProvider。自定义 ClientInfoProvider 可以配置如下:
Properties properties = new Properties();
properties.setProperty(PropertyKey.clientInfoProvider.getKeyName(), "foo.bar.CustomClientInfoProvider");
properties.setProperty(APPLICATION_NAME, "MyApp");
HikariConfig dataSourceConfig = new HikariConfig();
dataSourceConfig.setDataSourceProperties(properties);
...
但是只有当有人在连接中调用 getClientInfo 时才会调用它。
所以我想知道:
我认为你可以使用 AspectJ 作为一个可能的解决方案。您可以创建一个方面,它将拦截
DataSource.getConnection
方法的调用,然后在建立连接时使用配置的参数调用 setClientInfo
方法。
按照上面的
Ilya Lysenko
答案,我在我的Spring Boot应用程序中使用了这个方面,每次从getConnection
方法返回数据库连接时都会调用这个方面,然后使用这个方面我在连接对象中设置client info
。
@Component
@Aspect
@Slf4j
public class ConnectionAspect {
public ConnectionAspect() {
}
@AfterReturning(
pointcut = "execution(* *..*getConnection(..))",
returning = "connection"
)
public void afterReturningConnection(JoinPoint joinPoint, Connection connection) throws SQLClientInfoException {
LOGGER.debug("Connection Aspect triggered.");
connection.setClientInfo("OCSID.CLIENTID", "JAY");
}
}
}