diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java
index f25fd81c83..24cbb48272 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java
@@ -61,9 +61,13 @@ public class FlywayAutoConfiguration {
@Autowired
private ResourceLoader resourceLoader = new DefaultResourceLoader();
- @Autowired
+ @Autowired(required = false)
private DataSource dataSource;
+ @Autowired(required = false)
+ @FlywayDataSource
+ private DataSource flywayDataSource;
+
@PostConstruct
public void checkLocationExists() {
if (this.properties.isCheckLocation()) {
@@ -83,9 +87,19 @@ public class FlywayAutoConfiguration {
@Bean(initMethod = "migrate")
@ConfigurationProperties(prefix = "flyway")
- public Flyway flyway(DataSource dataSource) {
+ public Flyway flyway() {
Flyway flyway = new Flyway();
- flyway.setDataSource(dataSource);
+ if (this.properties.isCreateDataSource()) {
+ flyway.setDataSource(this.properties.getUrl(), this.properties.getUser(),
+ this.properties.getPassword(), this.properties.getInitSqls()
+ .toArray(new String[0]));
+ }
+ else if (this.flywayDataSource != null) {
+ flyway.setDataSource(this.flywayDataSource);
+ }
+ else {
+ flyway.setDataSource(this.dataSource);
+ }
return flyway;
}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayDataSource.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayDataSource.java
new file mode 100644
index 0000000000..4a97a90616
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayDataSource.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2012-2013 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.flyway;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+
+/**
+ * Qualifier annotation for a DataSource to be injected in to Flyway. If used for a second
+ * data source, the other (main) one would normally be marked as @Primary.
+ *
+ * @author Dave Syer
+ */
+@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
+ ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Qualifier
+public @interface FlywayDataSource {
+
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java
index 4b0a33f567..e7e6f0de36 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java
@@ -17,6 +17,7 @@
package org.springframework.boot.autoconfigure.flyway;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import org.flywaydb.core.Flyway;
@@ -41,6 +42,14 @@ public class FlywayProperties {
private boolean enabled = true;
+ private String user;
+
+ private String password;
+
+ private String url;
+
+ private List initSqls = Collections.emptyList();
+
public void setLocations(List locations) {
this.locations = locations;
}
@@ -64,4 +73,40 @@ public class FlywayProperties {
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
+
+ public String getUser() {
+ return this.user;
+ }
+
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ public String getPassword() {
+ return this.password == null ? "" : this.password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getUrl() {
+ return this.url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public List getInitSqls() {
+ return this.initSqls;
+ }
+
+ public void setInitSqls(List initSqls) {
+ this.initSqls = initSqls;
+ }
+
+ public boolean isCreateDataSource() {
+ return this.url != null && this.user != null;
+ }
}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBuilder.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBuilder.java
index 521fea24c3..be6c24d1f5 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBuilder.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBuilder.java
@@ -50,6 +50,8 @@ public class DataSourceBuilder {
private ClassLoader classLoader;
+ private DriverClassNameProvider driverClassNameProvider = new DriverClassNameProvider();
+
private Map properties = new HashMap();
public static DataSourceBuilder create() {
@@ -67,10 +69,19 @@ public class DataSourceBuilder {
public DataSource build() {
Class extends DataSource> type = getType();
DataSource result = BeanUtils.instantiate(type);
+ maybeGetDriverClassName();
bind(result);
return result;
}
+ private void maybeGetDriverClassName() {
+ if (!this.properties.containsKey("driverClassName")) {
+ String cls = this.driverClassNameProvider.getDriverClassName(this.properties
+ .get("url"));
+ this.properties.put("driverClassName", cls);
+ }
+ }
+
private void bind(DataSource result) {
new RelaxedDataBinder(result).bind(getPropertyValues());
}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java
index 72a17e23b0..ba969cb41a 100644
--- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java
@@ -18,6 +18,8 @@ package org.springframework.boot.autoconfigure.flyway;
import java.util.Arrays;
+import javax.sql.DataSource;
+
import org.flywaydb.core.Flyway;
import org.junit.After;
import org.junit.Before;
@@ -26,12 +28,16 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* Tests for {@link LiquibaseAutoConfiguration}.
@@ -66,6 +72,29 @@ public class FlywayAutoConfigurationTests {
assertEquals(0, this.context.getBeanNamesForType(Flyway.class).length);
}
+ @Test
+ public void testCreateDataSource() throws Exception {
+ EnvironmentTestUtils.addEnvironment(this.context,
+ "flyway.url:jdbc:hsqldb:mem:flywaytest", "flyway.user:sa");
+ this.context
+ .register(EmbeddedDataSourceConfiguration.class,
+ FlywayAutoConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class);
+ this.context.refresh();
+ Flyway flyway = this.context.getBean(Flyway.class);
+ assertNotNull(flyway.getDataSource());
+ }
+
+ @Test
+ public void testFlywayDataSource() throws Exception {
+ this.context.register(FlywayDataSourceConfiguration.class,
+ EmbeddedDataSourceConfiguration.class, FlywayAutoConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class);
+ this.context.refresh();
+ Flyway flyway = this.context.getBean(Flyway.class);
+ assertNotNull(flyway.getDataSource());
+ }
+
@Test
public void testDefaultFlyway() throws Exception {
this.context
@@ -113,4 +142,16 @@ public class FlywayAutoConfigurationTests {
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
}
+
+ @Configuration
+ protected static class FlywayDataSourceConfiguration {
+
+ @FlywayDataSource
+ @Bean
+ public DataSource flywayDataSource() {
+ return DataSourceBuilder.create().url("jdbc:hsqldb:mem:flywaytest")
+ .username("sa").build();
+ }
+
+ }
}
diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
index 39b7f4d401..e8cfd15803 100644
--- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
+++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
@@ -203,6 +203,9 @@ content into your application; rather pick only the properties that you need.
flyway.prefix=V
flyway.suffix=.sql
flyway.enabled=true
+ flyway.url= # JDBC url if you want Flyway to create its own DataSource
+ flyway.user= # JDBC username if you want Flyway to create its own DataSource
+ flyway.password= # JDBC password if you want Flyway to create its own DataSource
# LIQUIBASE ({sc-spring-boot-autoconfigure}/liquibase/LiquibaseProperties.{sc-ext}[LiquibaseProperties])
liquibase.change-log=classpath:/db/changelog/db.changelog-master.yaml
diff --git a/spring-boot-docs/src/main/asciidoc/howto.adoc b/spring-boot-docs/src/main/asciidoc/howto.adoc
index 40502bbb81..c8c4ae5f01 100644
--- a/spring-boot-docs/src/main/asciidoc/howto.adoc
+++ b/spring-boot-docs/src/main/asciidoc/howto.adoc
@@ -974,13 +974,13 @@ JDBC or JPA (then that one will be picked up by any `@Autowired` injections).
@Primary
@ConfigurationProperties(prefix="datasource.primary")
public DataSource primaryDataSource() {
- return new FancyDataSource();
+ return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix="datasource.secondary")
public DataSource secondaryDataSource() {
- return new FancyDataSource();
+ return DataSourceBuilder.create().build();
}
----
@@ -1207,6 +1207,13 @@ addition Spring Boot provides a small set of properties in
{sc-spring-boot-autoconfigure}/flyway/FlywayProperties.{sc-ext}[`FlywayProperties`]
that can be used to disable the migrations, or switch off the location checking.
+By default Flyway will autowire the (`@Primary`) `DataSource` in your context and
+use that for migrations. If you like to use a different `DataSource` you can create
+one and mark its `@Bean` as `@FlywayDataSource` - if you do that remember to create
+another one and mark it as `@Primary` if you want 2 data sources.
+Or you can use Flyway's native `DataSource` by setting `flyway.[url,user,password]`
+in external properties.
+
There is a {github-code}/spring-boot-samples/spring-boot-sample-flyway[Flyway sample] so
you can see how to set things up.