Commit 38a20f27 authored by Stephane Nicoll's avatar Stephane Nicoll

Merge pull request #16047 from clevertension

* pr/16047:
  Polish contribution
  Fix NamedParameterJdbcTemplate precedence with database migration tools
parents 2236e959 eebd906c
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -46,6 +46,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; ...@@ -46,6 +46,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.jdbc.JdbcOperationsDependsOnPostProcessor; import org.springframework.boot.autoconfigure.jdbc.JdbcOperationsDependsOnPostProcessor;
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.NamedParameterJdbcOperationsDependsOnPostProcessor;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
...@@ -57,6 +58,7 @@ import org.springframework.core.convert.TypeDescriptor; ...@@ -57,6 +58,7 @@ import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter; import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.MetaDataAccessException; import org.springframework.jdbc.support.MetaDataAccessException;
import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean; import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean;
...@@ -76,6 +78,7 @@ import org.springframework.util.StringUtils; ...@@ -76,6 +78,7 @@ import org.springframework.util.StringUtils;
* @author Jacques-Etienne Beaudet * @author Jacques-Etienne Beaudet
* @author Eddú Meléndez * @author Eddú Meléndez
* @author Dominic Gunn * @author Dominic Gunn
* @author Dan Zheng
* @since 1.1.0 * @since 1.1.0
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
...@@ -321,6 +324,23 @@ public class FlywayAutoConfiguration { ...@@ -321,6 +324,23 @@ public class FlywayAutoConfiguration {
public FlywayInitializerJdbcOperationsDependencyConfiguration() { public FlywayInitializerJdbcOperationsDependencyConfiguration() {
super("flywayInitializer"); super("flywayInitializer");
}
}
/**
* Additional configuration to ensure that {@link NamedParameterJdbcOperations}
* beans depend on the {@code flywayInitializer} bean.
*/
@Configuration
@ConditionalOnClass(NamedParameterJdbcOperations.class)
@ConditionalOnBean(NamedParameterJdbcOperations.class)
protected static class FlywayInitializerNamedParameterJdbcOperationsDependencyConfiguration
extends NamedParameterJdbcOperationsDependsOnPostProcessor {
public FlywayInitializerNamedParameterJdbcOperationsDependencyConfiguration() {
super("flywayInitializer");
} }
} }
...@@ -359,6 +379,22 @@ public class FlywayAutoConfiguration { ...@@ -359,6 +379,22 @@ public class FlywayAutoConfiguration {
} }
/**
* Additional configuration to ensure that {@link NamedParameterJdbcOperations} beans
* depend on the {@code flyway} bean.
*/
@Configuration
@ConditionalOnClass(NamedParameterJdbcOperations.class)
@ConditionalOnBean(NamedParameterJdbcOperations.class)
protected static class FlywayNamedParameterJdbcOperationsDependencyConfiguration
extends NamedParameterJdbcOperationsDependsOnPostProcessor {
public FlywayNamedParameterJdbcOperationsDependencyConfiguration() {
super("flyway");
}
}
private static class LocationResolver { private static class LocationResolver {
private static final String VENDOR_PLACEHOLDER = "{vendor}"; private static final String VENDOR_PLACEHOLDER = "{vendor}";
......
/*
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.jdbc;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
/**
* {@link BeanFactoryPostProcessor} that can be used to dynamically declare that all
* {@link NamedParameterJdbcOperations} beans should "depend on" one or more specific
* beans.
*
* @author Dan Zheng
* @since 2.1.4
* @see BeanDefinition#setDependsOn(String[])
*/
public class NamedParameterJdbcOperationsDependsOnPostProcessor
extends AbstractDependsOnBeanFactoryPostProcessor {
public NamedParameterJdbcOperationsDependsOnPostProcessor(String... dependsOn) {
super(NamedParameterJdbcOperations.class, dependsOn);
}
}
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -36,6 +36,7 @@ import org.springframework.boot.autoconfigure.data.jpa.EntityManagerFactoryDepen ...@@ -36,6 +36,7 @@ import org.springframework.boot.autoconfigure.data.jpa.EntityManagerFactoryDepen
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.jdbc.JdbcOperationsDependsOnPostProcessor; import org.springframework.boot.autoconfigure.jdbc.JdbcOperationsDependsOnPostProcessor;
import org.springframework.boot.autoconfigure.jdbc.NamedParameterJdbcOperationsDependsOnPostProcessor;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.jdbc.DataSourceBuilder;
...@@ -45,6 +46,7 @@ import org.springframework.context.annotation.Import; ...@@ -45,6 +46,7 @@ import org.springframework.context.annotation.Import;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean; import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.util.Assert; import org.springframework.util.Assert;
...@@ -58,6 +60,7 @@ import org.springframework.util.Assert; ...@@ -58,6 +60,7 @@ import org.springframework.util.Assert;
* @author Eddú Meléndez * @author Eddú Meléndez
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Dominic Gunn * @author Dominic Gunn
* @author Dan Zheng
* @since 1.1.0 * @since 1.1.0
*/ */
@Configuration @Configuration
...@@ -208,4 +211,20 @@ public class LiquibaseAutoConfiguration { ...@@ -208,4 +211,20 @@ public class LiquibaseAutoConfiguration {
} }
/**
* Additional configuration to ensure that {@link NamedParameterJdbcOperations} beans
* depend on the liquibase bean.
*/
@Configuration
@ConditionalOnClass(NamedParameterJdbcOperations.class)
@ConditionalOnBean(NamedParameterJdbcOperations.class)
protected static class LiquibaseNamedParameterJdbcOperationsDependencyConfiguration
extends NamedParameterJdbcOperationsDependsOnPostProcessor {
public LiquibaseNamedParameterJdbcOperationsDependencyConfiguration() {
super("liquibase");
}
}
} }
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure.jdbc; package org.springframework.boot.autoconfigure.jdbc;
import java.util.Collections;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.junit.Test; import org.junit.Test;
...@@ -41,6 +43,7 @@ import static org.mockito.Mockito.mock; ...@@ -41,6 +43,7 @@ import static org.mockito.Mockito.mock;
* @author Dave Syer * @author Dave Syer
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Kazuki Shimizu * @author Kazuki Shimizu
* @author Dan Zheng
*/ */
public class JdbcTemplateAutoConfigurationTests { public class JdbcTemplateAutoConfigurationTests {
...@@ -185,6 +188,21 @@ public class JdbcTemplateAutoConfigurationTests { ...@@ -185,6 +188,21 @@ public class JdbcTemplateAutoConfigurationTests {
}); });
} }
@Test
public void testDependencyToFlywayWithJdbcTemplateMixed() {
this.contextRunner
.withUserConfiguration(NamedParameterDataSourceMigrationValidator.class)
.withPropertyValues("spring.flyway.locations:classpath:db/city")
.withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class))
.run((context) -> {
assertThat(context).hasNotFailed();
assertThat(context.getBean(JdbcTemplate.class)).isNotNull();
assertThat(context.getBean(
NamedParameterDataSourceMigrationValidator.class).count)
.isEqualTo(0);
});
}
@Test @Test
public void testDependencyToLiquibase() { public void testDependencyToLiquibase() {
this.contextRunner.withUserConfiguration(DataSourceMigrationValidator.class) this.contextRunner.withUserConfiguration(DataSourceMigrationValidator.class)
...@@ -199,6 +217,23 @@ public class JdbcTemplateAutoConfigurationTests { ...@@ -199,6 +217,23 @@ public class JdbcTemplateAutoConfigurationTests {
}); });
} }
@Test
public void testDependencyToLiquibaseWithJdbcTemplateMixed() {
this.contextRunner
.withUserConfiguration(NamedParameterDataSourceMigrationValidator.class)
.withPropertyValues(
"spring.liquibase.changeLog:classpath:db/changelog/db.changelog-city.yaml")
.withConfiguration(
AutoConfigurations.of(LiquibaseAutoConfiguration.class))
.run((context) -> {
assertThat(context).hasNotFailed();
assertThat(context.getBean(JdbcTemplate.class)).isNotNull();
assertThat(context.getBean(
NamedParameterDataSourceMigrationValidator.class).count)
.isEqualTo(0);
});
}
@Configuration @Configuration
static class CustomConfiguration { static class CustomConfiguration {
...@@ -278,4 +313,16 @@ public class JdbcTemplateAutoConfigurationTests { ...@@ -278,4 +313,16 @@ public class JdbcTemplateAutoConfigurationTests {
} }
static class NamedParameterDataSourceMigrationValidator {
private final Integer count;
NamedParameterDataSourceMigrationValidator(
NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.count = namedParameterJdbcTemplate.queryForObject(
"SELECT COUNT(*) from CITY", Collections.emptyMap(), Integer.class);
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment