16
16
17
17
package org .springframework .boot .autoconfigure .jdbc ;
18
18
19
+ import java .util .HashMap ;
20
+ import java .util .Map ;
21
+
19
22
import javax .sql .DataSource ;
20
23
21
24
import org .junit .Test ;
22
25
26
+ import org .springframework .beans .BeansException ;
27
+ import org .springframework .beans .factory .NoSuchBeanDefinitionException ;
28
+ import org .springframework .beans .factory .config .BeanDefinition ;
29
+ import org .springframework .beans .factory .config .ConfigurableListableBeanFactory ;
30
+ import org .springframework .beans .factory .support .BeanDefinitionRegistry ;
31
+ import org .springframework .beans .factory .support .BeanDefinitionRegistryPostProcessor ;
23
32
import org .springframework .boot .autoconfigure .AutoConfigurations ;
33
+ import org .springframework .boot .autoconfigure .AutoConfigureAfter ;
34
+ import org .springframework .boot .autoconfigure .AutoConfigureBefore ;
35
+ import org .springframework .boot .autoconfigure .condition .ConditionalOnClass ;
36
+ import org .springframework .boot .autoconfigure .condition .ConditionalOnSingleCandidate ;
24
37
import org .springframework .boot .autoconfigure .flyway .FlywayAutoConfiguration ;
25
38
import org .springframework .boot .autoconfigure .liquibase .LiquibaseAutoConfiguration ;
39
+ import org .springframework .boot .context .properties .EnableConfigurationProperties ;
26
40
import org .springframework .boot .test .context .runner .ApplicationContextRunner ;
27
41
import org .springframework .context .annotation .Bean ;
28
42
import org .springframework .context .annotation .Configuration ;
33
47
import org .springframework .jdbc .core .namedparam .NamedParameterJdbcTemplate ;
34
48
35
49
import static org .assertj .core .api .Assertions .assertThat ;
50
+ import static org .junit .Assert .fail ;
36
51
import static org .mockito .Mockito .mock ;
37
52
38
53
/**
41
56
* @author Dave Syer
42
57
* @author Stephane Nicoll
43
58
* @author Kazuki Shimizu
59
+ * @author Dan Zheng
44
60
*/
45
61
public class JdbcTemplateAutoConfigurationTests {
46
62
@@ -185,6 +201,52 @@ public void testDependencyToFlyway() {
185
201
});
186
202
}
187
203
204
+ @ Test
205
+ public void testDependencyToFlywayWithJdbcTemplateMixed () {
206
+ this .contextRunner
207
+ .withUserConfiguration (NamedParameterDataSourceMigrationValidator .class )
208
+ .withPropertyValues ("spring.flyway.locations:classpath:db/city_np" )
209
+ .withConfiguration (AutoConfigurations .of (FlywayAutoConfiguration .class ))
210
+ .run ((context ) -> {
211
+ assertThat (context ).hasNotFailed ();
212
+ assertThat (context .getBean (JdbcTemplate .class )).isNotNull ();
213
+ assertThat (context .getBean (
214
+ NamedParameterDataSourceMigrationValidator .class ).count )
215
+ .isEqualTo (1 );
216
+ });
217
+ }
218
+
219
+ @ Test
220
+ public void testDependencyToFlywayWithOnlyNamedParameterJdbcTemplate () {
221
+ ApplicationContextRunner contextRunner1 = new ApplicationContextRunner ()
222
+ .withPropertyValues ("spring.datasource.initialization-mode=never" ,
223
+ "spring.datasource.generate-unique-name=true" )
224
+ .withConfiguration (
225
+ AutoConfigurations .of (DataSourceAutoConfiguration .class ,
226
+ JdbcTemplateAutoConfiguration .class ,
227
+ OnlyNamedParameterJdbcTemplateAutoConfiguration .class ));
228
+ contextRunner1
229
+ .withUserConfiguration (NamedParameterDataSourceMigrationValidator .class )
230
+ .withPropertyValues ("spring.flyway.locations:classpath:db/city_np" )
231
+ .withConfiguration (AutoConfigurations .of (FlywayAutoConfiguration .class ))
232
+ .run ((context ) -> {
233
+ assertThat (context ).hasNotFailed ();
234
+ assertThat (context .containsBean ("jdbcTemplate" )).isFalse ();
235
+ try {
236
+ JdbcTemplate jdbcTemplate = context .getBean (JdbcTemplate .class );
237
+ fail ("org.springframework.boot.autoconfigure.jdbc.JdcTemplate should not exist in the application context" );
238
+ }
239
+ catch (NoSuchBeanDefinitionException ex ) {
240
+
241
+ }
242
+ assertThat (context .getBean (NamedParameterJdbcTemplate .class ))
243
+ .isNotNull ();
244
+ assertThat (context .getBean (
245
+ NamedParameterDataSourceMigrationValidator .class ).count )
246
+ .isEqualTo (1 );
247
+ });
248
+ }
249
+
188
250
@ Test
189
251
public void testDependencyToLiquibase () {
190
252
this .contextRunner .withUserConfiguration (DataSourceMigrationValidator .class )
@@ -199,6 +261,50 @@ public void testDependencyToLiquibase() {
199
261
});
200
262
}
201
263
264
+ @ Test
265
+ public void testDependencyToLiquibaseWithJdbcTemplateMixed () {
266
+ this .contextRunner
267
+ .withUserConfiguration (NamedParameterDataSourceMigrationValidator .class )
268
+ .withPropertyValues (
269
+ "spring.liquibase.changeLog:classpath:db/changelog/db.changelog-city-np.yaml" )
270
+ .withConfiguration (
271
+ AutoConfigurations .of (LiquibaseAutoConfiguration .class ))
272
+ .run ((context ) -> {
273
+ assertThat (context ).hasNotFailed ();
274
+ assertThat (context .getBean (JdbcTemplate .class )).isNotNull ();
275
+ assertThat (context .getBean (
276
+ NamedParameterDataSourceMigrationValidator .class ).count )
277
+ .isEqualTo (1 );
278
+ });
279
+ }
280
+
281
+ @ Test
282
+ public void testDependencyToLiquibaseWithOnlyNamedParameterJdbcTemplate () {
283
+ this .contextRunner
284
+ .withUserConfiguration (NamedParameterDataSourceMigrationValidator .class )
285
+ .withPropertyValues (
286
+ "spring.liquibase.changeLog:classpath:db/changelog/db.changelog-city-np.yaml" )
287
+ .withConfiguration (AutoConfigurations .of (
288
+ OnlyNamedParameterJdbcTemplateAutoConfiguration .class ,
289
+ LiquibaseAutoConfiguration .class ))
290
+ .run ((context ) -> {
291
+ assertThat (context ).hasNotFailed ();
292
+ assertThat (context .containsBean ("jdbcTemplate" )).isFalse ();
293
+ try {
294
+ JdbcTemplate jdbcTemplate = context .getBean (JdbcTemplate .class );
295
+ fail ("org.springframework.boot.autoconfigure.jdbc.JdcTemplate should not exist in the application context" );
296
+ }
297
+ catch (NoSuchBeanDefinitionException ex ) {
298
+
299
+ }
300
+ assertThat (context .getBean (NamedParameterJdbcTemplate .class ))
301
+ .isNotNull ();
302
+ assertThat (context .getBean (
303
+ NamedParameterDataSourceMigrationValidator .class ).count )
304
+ .isEqualTo (1 );
305
+ });
306
+ }
307
+
202
308
@ Configuration
203
309
static class CustomConfiguration {
204
310
@@ -278,4 +384,66 @@ static class DataSourceMigrationValidator {
278
384
279
385
}
280
386
387
+ static class NamedParameterDataSourceMigrationValidator {
388
+
389
+ private final Integer count ;
390
+
391
+ NamedParameterDataSourceMigrationValidator (
392
+ NamedParameterJdbcTemplate namedParameterJdbcTemplate ) {
393
+ String sql = "SELECT COUNT(*) from CITY WHERE id = :id" ;
394
+ Map <String , Long > param = new HashMap <>();
395
+ param .put ("id" , 1L );
396
+ this .count = namedParameterJdbcTemplate .queryForObject (sql , param ,
397
+ Integer .class );
398
+ }
399
+
400
+ }
401
+
402
+ @ Configuration
403
+ @ ConditionalOnClass ({ DataSource .class })
404
+ @ ConditionalOnSingleCandidate (DataSource .class )
405
+ @ AutoConfigureAfter ({ DataSourceAutoConfiguration .class ,
406
+ JdbcTemplateAutoConfiguration .class })
407
+ @ AutoConfigureBefore ({ FlywayAutoConfiguration .class ,
408
+ LiquibaseAutoConfiguration .class })
409
+ @ EnableConfigurationProperties (JdbcProperties .class )
410
+ static class OnlyNamedParameterJdbcTemplateAutoConfiguration
411
+ implements BeanDefinitionRegistryPostProcessor {
412
+
413
+ @ Bean
414
+ public NamedParameterJdbcTemplate myNamedParameterJdbcTemplate (
415
+ DataSource dataSource ) {
416
+ return new NamedParameterJdbcTemplate (dataSource );
417
+ }
418
+
419
+ @ Override
420
+ public void postProcessBeanFactory (ConfigurableListableBeanFactory beanFactory )
421
+ throws BeansException {
422
+ // do nothing
423
+ }
424
+
425
+ /**
426
+ * <p>
427
+ * we should remove the jdbc template bean definition to keep only
428
+ * NamedParameterJdbcTemplate is registerd in the bean container
429
+ * </p>
430
+ * @param registry the bean definition registry.
431
+ * @throws BeansException if the bean registry have any exception.
432
+ */
433
+ @ Override
434
+ public void postProcessBeanDefinitionRegistry (BeanDefinitionRegistry registry )
435
+ throws BeansException {
436
+ String [] excludeBeanNames = new String [] { "jdbcTemplate" ,
437
+ "namedParameterJdbcTemplate" };
438
+ for (String beanName : excludeBeanNames ) {
439
+ BeanDefinition beanDefinition = registry .getBeanDefinition (beanName );
440
+ if (beanDefinition != null ) {
441
+ registry .removeBeanDefinition (beanName );
442
+ }
443
+ }
444
+
445
+ }
446
+
447
+ }
448
+
281
449
}
0 commit comments