Skip to content

Commit b103e0c

Browse files
committed
Polish "Unwrap DataSource target rather than plain instanceof calls"
Closes gh-15227
1 parent 98378e2 commit b103e0c

File tree

2 files changed

+58
-14
lines changed

2 files changed

+58
-14
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/HikariDataSourceMetricsPostProcessor.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.metrics.jdbc;
1818

19+
import javax.sql.DataSource;
20+
1921
import com.zaxxer.hikari.HikariDataSource;
2022
import com.zaxxer.hikari.metrics.micrometer.MicrometerMetricsTrackerFactory;
2123
import io.micrometer.core.instrument.MeterRegistry;
2224
import org.apache.commons.logging.Log;
2325
import org.apache.commons.logging.LogFactory;
2426

2527
import org.springframework.beans.factory.config.BeanPostProcessor;
28+
import org.springframework.boot.jdbc.DataSourceUnwrapper;
2629
import org.springframework.context.ApplicationContext;
2730
import org.springframework.core.Ordered;
2831

@@ -48,13 +51,21 @@ class HikariDataSourceMetricsPostProcessor implements BeanPostProcessor, Ordered
4851

4952
@Override
5053
public Object postProcessAfterInitialization(Object bean, String beanName) {
51-
if (bean instanceof HikariDataSource) {
52-
bindMetricsRegistryToHikariDataSource(getMeterRegistry(),
53-
(HikariDataSource) bean);
54+
HikariDataSource hikariDataSource = determineHikariDataSource(bean);
55+
if (hikariDataSource != null) {
56+
bindMetricsRegistryToHikariDataSource(getMeterRegistry(), hikariDataSource);
5457
}
5558
return bean;
5659
}
5760

61+
private HikariDataSource determineHikariDataSource(Object bean) {
62+
if (!(bean instanceof DataSource)) {
63+
return null;
64+
}
65+
DataSource dataSource = (DataSource) bean;
66+
return DataSourceUnwrapper.unwrap(dataSource, HikariDataSource.class);
67+
}
68+
5869
private void bindMetricsRegistryToHikariDataSource(MeterRegistry registry,
5970
HikariDataSource dataSource) {
6071
if (dataSource.getMetricRegistry() == null

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
2828
import org.junit.Test;
2929

30+
import org.springframework.aop.framework.ProxyFactory;
3031
import org.springframework.beans.BeansException;
3132
import org.springframework.beans.factory.config.BeanPostProcessor;
3233
import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun;
@@ -39,6 +40,7 @@
3940
import org.springframework.context.annotation.Configuration;
4041
import org.springframework.core.Ordered;
4142
import org.springframework.core.PriorityOrdered;
43+
import org.springframework.jdbc.datasource.DelegatingDataSource;
4244

4345
import static org.assertj.core.api.Assertions.assertThat;
4446

@@ -185,6 +187,25 @@ public void someHikariDataSourcesCanBeInstrumented() {
185187
});
186188
}
187189

190+
@Test
191+
public void hikariProxiedDataSourceCanBeInstrumented() {
192+
this.contextRunner
193+
.withUserConfiguration(ProxiedHikariDataSourcesConfiguration.class)
194+
.withConfiguration(
195+
AutoConfigurations.of(DataSourceAutoConfiguration.class))
196+
.run((context) -> {
197+
context.getBean("proxiedDataSource", DataSource.class)
198+
.getConnection();
199+
context.getBean("delegateDataSource", DataSource.class)
200+
.getConnection();
201+
MeterRegistry registry = context.getBean(MeterRegistry.class);
202+
registry.get("hikaricp.connections").tags("pool", "firstDataSource")
203+
.meter();
204+
registry.get("hikaricp.connections").tags("pool", "secondOne")
205+
.meter();
206+
});
207+
}
208+
188209
@Test
189210
public void hikariDataSourceIsInstrumentedWithoutMetadataProvider() {
190211
this.contextRunner.withUserConfiguration(OneHikariDataSourceConfiguration.class)
@@ -199,6 +220,14 @@ public void hikariDataSourceIsInstrumentedWithoutMetadataProvider() {
199220
});
200221
}
201222

223+
private static HikariDataSource createHikariDataSource(String poolName) {
224+
String url = "jdbc:hsqldb:mem:test-" + UUID.randomUUID();
225+
HikariDataSource hikariDataSource = DataSourceBuilder.create().url(url)
226+
.type(HikariDataSource.class).build();
227+
hikariDataSource.setPoolName(poolName);
228+
return hikariDataSource;
229+
}
230+
202231
@Configuration
203232
static class BaseConfiguration {
204233

@@ -242,12 +271,20 @@ public DataSource secondOne() {
242271
return createHikariDataSource("secondOne");
243272
}
244273

245-
private HikariDataSource createHikariDataSource(String poolName) {
246-
String url = "jdbc:hsqldb:mem:test-" + UUID.randomUUID();
247-
HikariDataSource hikariDataSource = DataSourceBuilder.create().url(url)
248-
.type(HikariDataSource.class).build();
249-
hikariDataSource.setPoolName(poolName);
250-
return hikariDataSource;
274+
}
275+
276+
@Configuration
277+
static class ProxiedHikariDataSourcesConfiguration {
278+
279+
@Bean
280+
public DataSource proxiedDataSource() {
281+
return (DataSource) new ProxyFactory(
282+
createHikariDataSource("firstDataSource")).getProxy();
283+
}
284+
285+
@Bean
286+
public DataSource delegateDataSource() {
287+
return new DelegatingDataSource(createHikariDataSource("secondOne"));
251288
}
252289

253290
}
@@ -257,11 +294,7 @@ static class OneHikariDataSourceConfiguration {
257294

258295
@Bean
259296
public DataSource hikariDataSource() {
260-
String url = "jdbc:hsqldb:mem:test-" + UUID.randomUUID();
261-
HikariDataSource hikariDataSource = DataSourceBuilder.create().url(url)
262-
.type(HikariDataSource.class).build();
263-
hikariDataSource.setPoolName("hikariDataSource");
264-
return hikariDataSource;
297+
return createHikariDataSource("hikariDataSource");
265298
}
266299

267300
}

0 commit comments

Comments
 (0)