Skip to content

Commit 5f8fb26

Browse files
authored
Optional decoration of routing datasources (#74)
* Optional decorating of routing datasources Add property to allow disable decorating of AbstractRoutingDataSSource * Add some test * Update README.md
1 parent 3bf37ac commit 5f8fb26

File tree

4 files changed

+69
-1
lines changed

4 files changed

+69
-1
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -289,4 +289,6 @@ public DataSourceDecorator customDecorator() {
289289

290290
#### Disable Decorating
291291

292-
If you want to disable decorating set `decorator.datasource.exclude-beans` with bean names you want to exclude or set `decorator.datasource.enabled` to `false` if you want to disable all decorators for all datasources.
292+
If you want to disable decorating set `decorator.datasource.exclude-beans` with bean names you want to exclude.
293+
Also, you can disable decorating for `AbstractRoutingDataSource` setting property `decorator.datasource.ignore-routing-data-sources` to `true`
294+
Set `decorator.datasource.enabled` to `false` if you want to disable all decorators for all datasources.

datasource-decorator-spring-boot-autoconfigure/src/main/java/com/github/gavlyukovskiy/boot/jdbc/decorator/DataSourceDecoratorBeanPostProcessor.java

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.springframework.context.ApplicationContextAware;
2424
import org.springframework.core.Ordered;
2525
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
26+
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
2627

2728
import javax.sql.DataSource;
2829
import java.util.ArrayList;
@@ -52,6 +53,7 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro
5253
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
5354
if (bean instanceof DataSource
5455
&& !ScopedProxyUtils.isScopedTarget(beanName)
56+
&& !((bean instanceof AbstractRoutingDataSource) && getDataSourceDecoratorProperties().isIgnoreRoutingDataSources())
5557
&& !getDataSourceDecoratorProperties().getExcludeBeans().contains(beanName)) {
5658
DataSource dataSource = (DataSource) bean;
5759
DataSource decoratedDataSource = dataSource;

datasource-decorator-spring-boot-autoconfigure/src/main/java/com/github/gavlyukovskiy/boot/jdbc/decorator/DataSourceDecoratorProperties.java

+14
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ public class DataSourceDecoratorProperties {
4343
* Beans that won't be decorated.
4444
*/
4545
private Collection<String> excludeBeans = Collections.emptyList();
46+
47+
/**
48+
* If AbstractRoutingDataSource will be decorated or not
49+
*/
50+
private boolean ignoreRoutingDataSources = false;
4651

4752
@NestedConfigurationProperty
4853
private DataSourceProxyProperties datasourceProxy = new DataSourceProxyProperties();
@@ -68,6 +73,10 @@ public Collection<String> getExcludeBeans() {
6873
return this.excludeBeans;
6974
}
7075

76+
public boolean isIgnoreRoutingDataSources() {
77+
return ignoreRoutingDataSources;
78+
}
79+
7180
public DataSourceProxyProperties getDatasourceProxy() {
7281
return this.datasourceProxy;
7382
}
@@ -97,6 +106,11 @@ public void setExcludeBeans(Collection<String> excludeBeans) {
97106
this.excludeBeans = excludeBeans;
98107
}
99108

109+
public void setIgnoreRoutingDataSources(boolean ignoreRoutingDataSources) {
110+
this.ignoreRoutingDataSources = ignoreRoutingDataSources;
111+
}
112+
113+
100114
public void setDatasourceProxy(DataSourceProxyProperties datasourceProxy) {
101115
this.datasourceProxy = datasourceProxy;
102116
}

datasource-decorator-spring-boot-autoconfigure/src/test/java/com/github/gavlyukovskiy/boot/jdbc/decorator/DataSourceDecoratorAutoConfigurationTests.java

+50
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,14 @@
3535
import org.springframework.context.annotation.Scope;
3636
import org.springframework.context.annotation.ScopedProxyMode;
3737
import org.springframework.context.support.GenericApplicationContext;
38+
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
3839

3940
import javax.sql.DataSource;
4041
import java.io.PrintWriter;
4142
import java.sql.Connection;
4243
import java.util.List;
44+
import java.util.HashMap;
45+
import java.util.Map;
4346
import java.util.concurrent.ThreadLocalRandom;
4447
import java.util.logging.Logger;
4548

@@ -226,6 +229,30 @@ void testDecorateDynamicallyRegisteredBeans() {
226229
assertThat(dataSource2).isInstanceOf(DecoratedDataSource.class);
227230
});
228231
}
232+
233+
@Test
234+
void testRoutingDataSourceIsDecorated() {
235+
ApplicationContextRunner contextRunner = this.contextRunner.withUserConfiguration(TestAbstractRoutingDataSourceConfiguration.class);
236+
237+
contextRunner.run(context -> {
238+
DataSource dataSource = context.getBean(DataSource.class);
239+
assertThat(dataSource).isInstanceOf(DecoratedDataSource.class);
240+
DataSource realDataSource = ((DecoratedDataSource) dataSource).getRealDataSource();
241+
assertThat(realDataSource).isInstanceOf(AbstractRoutingDataSource.class);
242+
});
243+
}
244+
245+
@Test
246+
void testRoutingDataSourceIsNotDecorated() {
247+
ApplicationContextRunner contextRunner = this.contextRunner.withPropertyValues("decorator.datasource.ignore-routing-data-sources=true")
248+
.withUserConfiguration(TestAbstractRoutingDataSourceConfiguration.class);
249+
250+
contextRunner.run(context -> {
251+
DataSource dataSource = context.getBean(DataSource.class);
252+
assertThat(dataSource).isNotInstanceOf(DecoratedDataSource.class);
253+
assertThat(dataSource).isInstanceOf(AbstractRoutingDataSource.class);
254+
});
255+
}
229256

230257
private AbstractListAssert<?, List<?>, Object, ObjectAssert<Object>> assertThatDataSourceDecoratingChain(DataSource dataSource) {
231258
return assertThat(((DecoratedDataSource) dataSource).getDecoratingChain()).extracting("dataSource").extracting("class");
@@ -289,6 +316,29 @@ public DataSource dataSource() {
289316
return pool;
290317
}
291318
}
319+
320+
@Configuration(proxyBeanMethods = false)
321+
static class TestAbstractRoutingDataSourceConfiguration {
322+
323+
@Bean
324+
public DataSource dataSource() {
325+
AbstractRoutingDataSource routingDs = new AbstractRoutingDataSource() {
326+
@Override
327+
protected Object determineCurrentLookupKey() {
328+
return "ds1";
329+
}
330+
};
331+
BasicDataSource pool = new BasicDataSource();
332+
pool.setDriverClassName("org.hsqldb.jdbcDriver");
333+
pool.setUrl("jdbc:hsqldb:target/routingds");
334+
pool.setUsername("sa");
335+
Map<Object, Object> targetDataSources = new HashMap<>();
336+
targetDataSources.put("ds1", pool);
337+
routingDs.setTargetDataSources(targetDataSources);
338+
routingDs.setDefaultTargetDataSource(pool);
339+
return routingDs;
340+
}
341+
}
292342

293343
/**
294344
* Custom proxy data source for tests.

0 commit comments

Comments
 (0)