From 2dc296caa9bccb3bd64807b843e578b6cee18c3e Mon Sep 17 00:00:00 2001
From: Dave Syer
Date: Fri, 17 May 2013 11:57:02 +0100
Subject: [PATCH] [bs-98] Add support for Tomcat database pool
* If Tomcat jdbc is available and the driverClassName and url
are provided or can be guessed (e.g. for HSQL) it is used.
Properties spring.database.{driverClassName,url} are consulted.
* If Commons DBCP is available it is used (if Tomcat is not)
* Otherwise an EmbeddedDatabase is created if all the bits are
available
* A JdbcOperations and a NamedParameterJdbcOperations are
available by default if a DataSource is created
* The data source is initialized from spring.database.schema (csv
of resource patterns)
[Fixes #49393511]
---
.../jdbc/AbstractDataSourceConfiguration.java | 86 ++++++
.../jdbc/BasicDataSourceConfiguration.java | 44 +++
.../jdbc/DataSourceAutoConfiguration.java | 266 ++++++++++++++++++
.../EmbeddedDatabaseAutoConfiguration.java | 119 --------
.../jdbc/EmbeddedDatabaseConfiguration.java | 80 ++++++
.../jdbc/TomcatDataSourceConfiguration.java | 43 +++
.../jpa/HibernateJpaAutoConfiguration.java | 4 +-
.../orm/jpa/JpaAutoConfiguration.java | 6 +-
.../web/WebMvcAutoConfiguration.java | 23 ++
.../initializer/LoggingInitializer.java | 221 ---------------
...JpaRepositoriesAutoConfigurationTests.java | 4 +-
...BasicDataSourceAutoConfigurationTests.java | 40 +++
.../DataSourceAutoConfigurationTests.java | 88 ++++++
...mbeddedDatabaseAutoConfigurationTests.java | 41 +++
...omcatDataSourceAutoConfigurationTests.java | 40 +++
.../bootstrap/autoconfigure/jdbc/schema.sql | 4 +
16 files changed, 762 insertions(+), 347 deletions(-)
create mode 100644 spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/AbstractDataSourceConfiguration.java
create mode 100644 spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/BasicDataSourceConfiguration.java
create mode 100644 spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/DataSourceAutoConfiguration.java
delete mode 100644 spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseAutoConfiguration.java
create mode 100644 spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseConfiguration.java
create mode 100644 spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/TomcatDataSourceConfiguration.java
delete mode 100644 spring-bootstrap/src/main/java/org/springframework/bootstrap/context/initializer/LoggingInitializer.java
create mode 100644 spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/BasicDataSourceAutoConfigurationTests.java
create mode 100644 spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/DataSourceAutoConfigurationTests.java
create mode 100644 spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseAutoConfigurationTests.java
create mode 100644 spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/TomcatDataSourceAutoConfigurationTests.java
create mode 100644 spring-bootstrap/src/test/resources/org/springframework/bootstrap/autoconfigure/jdbc/schema.sql
diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/AbstractDataSourceConfiguration.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/AbstractDataSourceConfiguration.java
new file mode 100644
index 0000000000..c1e58eca88
--- /dev/null
+++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/AbstractDataSourceConfiguration.java
@@ -0,0 +1,86 @@
+/*
+ * 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.bootstrap.autoconfigure.jdbc;
+
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+import org.springframework.util.StringUtils;
+
+/**
+ * Base class for configuration of a database pool.
+ *
+ * @author Dave Syer
+ *
+ */
+public class AbstractDataSourceConfiguration {
+
+ // TODO: add pool parameters
+
+ @Value("${spring.database.driverClassName:}")
+ private String driverClassName;
+
+ @Value("${spring.database.url:}")
+ private String url;
+
+ @Value("${spring.database.username:sa}")
+ private String username;
+
+ @Value("${spring.database.password:}")
+ private String password;
+
+ protected String getDriverClassName() {
+ if (StringUtils.hasText(this.driverClassName)) {
+ return this.driverClassName;
+ }
+ EmbeddedDatabaseType embeddedDatabaseType = EmbeddedDatabaseConfiguration
+ .getEmbeddedDatabaseType();
+ this.driverClassName = EmbeddedDatabaseConfiguration
+ .getEmbeddedDatabaseDriverClass(embeddedDatabaseType);
+ if (!StringUtils.hasText(this.driverClassName)) {
+ throw new BeanCreationException(
+ "Cannot determine embedded database driver class for database type "
+ + embeddedDatabaseType
+ + ". If you want an embedded database please put a supoprted one on the classpath.");
+ }
+ return this.driverClassName;
+ }
+
+ protected String getUrl() {
+ if (StringUtils.hasText(this.url)) {
+ return this.url;
+ }
+ EmbeddedDatabaseType embeddedDatabaseType = EmbeddedDatabaseConfiguration
+ .getEmbeddedDatabaseType();
+ this.url = EmbeddedDatabaseConfiguration
+ .getEmbeddedDatabaseUrl(embeddedDatabaseType);
+ if (!StringUtils.hasText(this.driverClassName)) {
+ throw new BeanCreationException(
+ "Cannot determine embedded database url for database type "
+ + embeddedDatabaseType
+ + ". If you want an embedded database please put a supported on on the classpath.");
+ }
+ return this.url;
+ }
+
+ protected String getUsername() {
+ return this.username;
+ }
+
+ protected String getPassword() {
+ return this.password;
+ }
+}
diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/BasicDataSourceConfiguration.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/BasicDataSourceConfiguration.java
new file mode 100644
index 0000000000..59e3b5a064
--- /dev/null
+++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/BasicDataSourceConfiguration.java
@@ -0,0 +1,44 @@
+/*
+ * 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.bootstrap.autoconfigure.jdbc;
+
+import javax.sql.DataSource;
+
+import org.apache.commons.dbcp.BasicDataSource;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Configuration for a Commons DBCP database pool. The DBCP pool is popular but not
+ * recommended in high volume environments.
+ *
+ * @author Dave Syer
+ *
+ */
+@Configuration
+public class BasicDataSourceConfiguration extends AbstractDataSourceConfiguration {
+
+ @Bean
+ public DataSource dataSource() {
+ BasicDataSource pool = new BasicDataSource();
+ pool.setDriverClassName(getDriverClassName());
+ pool.setUrl(getUrl());
+ pool.setUsername(getUsername());
+ pool.setPassword(getPassword());
+ return pool;
+ }
+
+}
diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/DataSourceAutoConfiguration.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/DataSourceAutoConfiguration.java
new file mode 100644
index 0000000000..f204b86e19
--- /dev/null
+++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/DataSourceAutoConfiguration.java
@@ -0,0 +1,266 @@
+/*
+ * 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.bootstrap.autoconfigure.jdbc;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+import javax.sql.DataSource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.BeanFactoryUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.bootstrap.context.annotation.ConditionalOnClass;
+import org.springframework.bootstrap.context.annotation.ConditionalOnMissingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Condition;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.core.io.Resource;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+import org.springframework.jdbc.core.JdbcOperations;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
+import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.StringUtils;
+
+/**
+ * @author Dave Syer
+ *
+ */
+@Configuration
+@ConditionalOnClass(EmbeddedDatabaseType.class /* Spring JDBC */)
+// @ConditionalOnMissingBean(DataSource.class)
+public class DataSourceAutoConfiguration {
+
+ private static Log logger = LogFactory.getLog(DataSourceAutoConfiguration.class);
+
+ @Autowired(required = false)
+ private DataSource dataSource;
+
+ @Autowired
+ private ApplicationContext applicationContext;
+
+ @Conditional(DataSourceAutoConfiguration.EmbeddedDatabaseCondition.class)
+ @Import(EmbeddedDatabaseConfiguration.class)
+ protected static class EmbeddedConfiguration {
+ }
+
+ @Conditional(DataSourceAutoConfiguration.TomcatDatabaseCondition.class)
+ @Import(TomcatDataSourceConfiguration.class)
+ protected static class TomcatConfiguration {
+ }
+
+ @Conditional(DataSourceAutoConfiguration.BasicDatabaseCondition.class)
+ @Import(BasicDataSourceConfiguration.class)
+ protected static class DbcpConfiguration {
+ }
+
+ @Configuration
+ @Conditional(DataSourceAutoConfiguration.SomeDatabaseCondition.class)
+ // FIXME: make this @ConditionalOnBean(DataSorce.class)
+ protected static class JdbcTemplateConfiguration {
+
+ @Autowired(required = false)
+ private DataSource dataSource;
+
+ @Bean
+ @ConditionalOnMissingBean(JdbcOperations.class)
+ public JdbcOperations jdbcTemplate() {
+ return new JdbcTemplate(this.dataSource);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean(NamedParameterJdbcOperations.class)
+ public NamedParameterJdbcOperations namedParameterJdbcTemplate() {
+ return new NamedParameterJdbcTemplate(this.dataSource);
+ }
+
+ }
+
+ // FIXME: DB platform
+ @Value("${spring.database.schema:classpath*:schema.sql}")
+ private String schemaLocations = "";
+
+ @PostConstruct
+ protected void initialize() throws Exception {
+ if (this.dataSource == null) {
+ logger.debug("No DataSource found so not initializing");
+ return;
+ }
+ ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
+ boolean exists = false;
+ List resources = new ArrayList();
+ for (String location : StringUtils
+ .commaDelimitedListToStringArray(this.schemaLocations)) {
+ resources
+ .addAll(Arrays.asList(this.applicationContext.getResources(location)));
+ }
+ for (Resource resource : resources) {
+ if (resource.exists()) {
+ exists = true;
+ populator.addScript(resource);
+ populator.setContinueOnError(true);
+ }
+ }
+ if (exists) {
+ DatabasePopulatorUtils.execute(populator, this.dataSource);
+ }
+ }
+
+ static class SomeDatabaseCondition implements Condition {
+
+ protected Log logger = LogFactory.getLog(getClass());
+
+ private Condition tomcatCondition = new TomcatDatabaseCondition();
+
+ private Condition dbcpCondition = new BasicDatabaseCondition();
+
+ private Condition embeddedCondition = new EmbeddedDatabaseCondition();
+
+ @Override
+ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ if (this.tomcatCondition.matches(context, metadata)
+ || this.dbcpCondition.matches(context, metadata)
+ || this.embeddedCondition.matches(context, metadata)) {
+ if (this.logger.isDebugEnabled()) {
+ this.logger
+ .debug("Existing auto database detected: match result true");
+ }
+ return true;
+ }
+ if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
+ context.getBeanFactory(), DataSource.class, true, false).length > 0) {
+ if (this.logger.isDebugEnabled()) {
+ this.logger
+ .debug("Existing bean configured database detected: match result true");
+ }
+ return true;
+ }
+ return false;
+ }
+
+ }
+
+ static class TomcatDatabaseCondition extends NonEmbeddedDatabaseCondition {
+
+ @Override
+ protected String getDataSourecClassName() {
+ return "org.apache.tomcat.jdbc.pool.DataSource";
+ }
+
+ }
+
+ static class BasicDatabaseCondition extends NonEmbeddedDatabaseCondition {
+
+ private Condition condition = new TomcatDatabaseCondition();
+
+ @Override
+ protected String getDataSourecClassName() {
+ return "org.apache.commons.dbcp.BasicDataSource";
+ }
+
+ @Override
+ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ if (this.condition.matches(context, metadata)) {
+ return false; // prefer Tomcat pool
+ }
+ return super.matches(context, metadata);
+ }
+
+ }
+
+ static abstract class NonEmbeddedDatabaseCondition implements Condition {
+
+ protected Log logger = LogFactory.getLog(getClass());
+
+ protected abstract String getDataSourecClassName();
+
+ @Override
+ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ if (!ClassUtils.isPresent(getDataSourecClassName(), null)) {
+ if (this.logger.isDebugEnabled()) {
+ this.logger.debug("Tomcat DataSource pool not found");
+ }
+ return false;
+ }
+ String driverClassName = context.getEnvironment().getProperty(
+ "spring.database.driverClassName");
+ String url = context.getEnvironment().getProperty("spring.database.url");
+ if (this.logger.isDebugEnabled()) {
+ this.logger.debug("Spring JDBC detected (embedded database type is "
+ + EmbeddedDatabaseConfiguration.getEmbeddedDatabaseType() + ").");
+ }
+ if (driverClassName == null) {
+ driverClassName = EmbeddedDatabaseConfiguration
+ .getEmbeddedDatabaseDriverClass(EmbeddedDatabaseConfiguration
+ .getEmbeddedDatabaseType());
+ }
+ if (url == null) {
+ url = EmbeddedDatabaseConfiguration
+ .getEmbeddedDatabaseUrl(EmbeddedDatabaseConfiguration
+ .getEmbeddedDatabaseType());
+ }
+ if (driverClassName != null && url != null
+ && ClassUtils.isPresent(driverClassName, null)) {
+ if (this.logger.isDebugEnabled()) {
+ this.logger.debug("Driver class " + driverClassName + " found");
+ }
+ return true;
+ }
+ return false;
+ }
+
+ }
+
+ static class EmbeddedDatabaseCondition implements Condition {
+
+ protected Log logger = LogFactory.getLog(getClass());
+
+ private Condition tomcatCondition = new TomcatDatabaseCondition();
+
+ private Condition dbcpCondition = new BasicDatabaseCondition();
+
+ @Override
+ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ if (this.tomcatCondition.matches(context, metadata)
+ || this.dbcpCondition.matches(context, metadata)) {
+ if (this.logger.isDebugEnabled()) {
+ this.logger
+ .debug("Existing non-embedded database detected: match result false");
+ }
+ return false;
+ }
+ if (this.logger.isDebugEnabled()) {
+ this.logger.debug("Spring JDBC detected (embedded database type is "
+ + EmbeddedDatabaseConfiguration.getEmbeddedDatabaseType() + ").");
+ }
+ return EmbeddedDatabaseConfiguration.getEmbeddedDatabaseType() != null;
+ }
+ }
+
+}
diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseAutoConfiguration.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseAutoConfiguration.java
deleted file mode 100644
index 4523685c41..0000000000
--- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseAutoConfiguration.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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.bootstrap.autoconfigure.jdbc;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import javax.annotation.PostConstruct;
-import javax.sql.DataSource;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.bootstrap.context.annotation.ConditionalOnMissingBean;
-import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Condition;
-import org.springframework.context.annotation.ConditionContext;
-import org.springframework.context.annotation.Conditional;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.io.Resource;
-import org.springframework.core.type.AnnotatedTypeMetadata;
-import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
-import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
-import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
-import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
-import org.springframework.util.ClassUtils;
-
-/**
- * {@link EnableAutoConfiguration Auto-configuration} for embedded databases.
- *
- * @author Phillip Webb
- */
-@Configuration
-@Conditional(EmbeddedDatabaseAutoConfiguration.EmbeddedDatabaseCondition.class)
-@ConditionalOnMissingBean(DataSource.class)
-public class EmbeddedDatabaseAutoConfiguration {
-
- private static final Map EMBEDDED_DATABASE_TYPE_CLASSES;
- static {
- EMBEDDED_DATABASE_TYPE_CLASSES = new LinkedHashMap();
- EMBEDDED_DATABASE_TYPE_CLASSES.put(EmbeddedDatabaseType.HSQL,
- "org.hsqldb.Database");
- }
-
- // FIXME: DB platform
- @Value("${spring.jdbc.schema:classpath*:schema.sql}")
- private Resource[] schemaLocations = new Resource[0];
-
- @PostConstruct
- protected void initialize() throws Exception {
- ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
- boolean exists = false;
- for (Resource resource : this.schemaLocations) {
- if (resource.exists()) {
- exists = true;
- populator.addScript(resource);
- populator.setContinueOnError(true);
- }
- }
- if (exists) {
- DatabasePopulatorUtils.execute(populator, dataSource());
- }
- }
-
- @Bean
- public DataSource dataSource() {
- EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
- .setType(getEmbeddedDatabaseType());
- return builder.build();
- }
-
- public static EmbeddedDatabaseType getEmbeddedDatabaseType() {
- for (Map.Entry entry : EMBEDDED_DATABASE_TYPE_CLASSES
- .entrySet()) {
- if (ClassUtils.isPresent(entry.getValue(),
- EmbeddedDatabaseAutoConfiguration.class.getClassLoader())) {
- return entry.getKey();
- }
- }
- return null;
- }
-
- static class EmbeddedDatabaseCondition implements Condition {
-
- private static Log logger = LogFactory.getLog(EmbeddedDatabaseCondition.class);
-
- @Override
- public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
- if (!ClassUtils.isPresent(
- "org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType",
- context.getClassLoader())) {
- if (logger.isDebugEnabled()) {
- logger.debug("Spring JDBC not detected (EmbeddedDatabaseCondition evaluated false).");
- }
- return false;
- }
- if (logger.isDebugEnabled()) {
- logger.debug("Spring JDBC detected (embedded database type is "
- + getEmbeddedDatabaseType() + ").");
- }
- return getEmbeddedDatabaseType() != null;
- }
- }
-}
diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseConfiguration.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseConfiguration.java
new file mode 100644
index 0000000000..a4998a6f2e
--- /dev/null
+++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseConfiguration.java
@@ -0,0 +1,80 @@
+/*
+ * 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.bootstrap.autoconfigure.jdbc;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.sql.DataSource;
+
+import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+import org.springframework.util.ClassUtils;
+
+/**
+ * {@link EnableAutoConfiguration Auto-configuration} for embedded databases.
+ *
+ * @author Phillip Webb
+ */
+@Configuration
+public class EmbeddedDatabaseConfiguration {
+
+ private static final Map EMBEDDED_DATABASE_TYPE_CLASSES;
+ private static final Map EMBEDDED_DATABASE_DRIVER_CLASSES;
+ private static final Map EMBEDDED_DATABASE_URLS;
+ static {
+ EMBEDDED_DATABASE_TYPE_CLASSES = new LinkedHashMap();
+ EMBEDDED_DATABASE_TYPE_CLASSES.put(EmbeddedDatabaseType.HSQL,
+ "org.hsqldb.Database");
+ EMBEDDED_DATABASE_DRIVER_CLASSES = new LinkedHashMap();
+ EMBEDDED_DATABASE_DRIVER_CLASSES.put(EmbeddedDatabaseType.HSQL,
+ "org.hsqldb.jdbcDriver");
+ EMBEDDED_DATABASE_URLS = new LinkedHashMap();
+ EMBEDDED_DATABASE_URLS.put(EmbeddedDatabaseType.HSQL, "jdbc:hsqldb:mem:testdb");
+ }
+
+ @Bean
+ public DataSource dataSource() {
+ EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
+ .setType(getEmbeddedDatabaseType());
+ return builder.build();
+ }
+
+ public static String getEmbeddedDatabaseDriverClass(
+ EmbeddedDatabaseType embeddedDatabaseType) {
+ return EMBEDDED_DATABASE_DRIVER_CLASSES.get(embeddedDatabaseType);
+ }
+
+ public static String getEmbeddedDatabaseUrl(EmbeddedDatabaseType embeddedDatabaseType) {
+ return EMBEDDED_DATABASE_URLS.get(embeddedDatabaseType);
+ }
+
+ public static EmbeddedDatabaseType getEmbeddedDatabaseType() {
+ for (Map.Entry entry : EMBEDDED_DATABASE_TYPE_CLASSES
+ .entrySet()) {
+ if (ClassUtils.isPresent(entry.getValue(),
+ EmbeddedDatabaseConfiguration.class.getClassLoader())) {
+ return entry.getKey();
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/TomcatDataSourceConfiguration.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/TomcatDataSourceConfiguration.java
new file mode 100644
index 0000000000..344a810812
--- /dev/null
+++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/TomcatDataSourceConfiguration.java
@@ -0,0 +1,43 @@
+/*
+ * 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.bootstrap.autoconfigure.jdbc;
+
+import javax.sql.DataSource;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Configuration for a Tomcat database pool. The Tomcat pool provides superior performance
+ * and tends not to deadlock in high volume environments.
+ *
+ * @author Dave Syer
+ *
+ */
+@Configuration
+public class TomcatDataSourceConfiguration extends AbstractDataSourceConfiguration {
+
+ @Bean
+ public DataSource dataSource() {
+ org.apache.tomcat.jdbc.pool.DataSource pool = new org.apache.tomcat.jdbc.pool.DataSource();
+ pool.setDriverClassName(getDriverClassName());
+ pool.setUrl(getUrl());
+ pool.setUsername(getUsername());
+ pool.setPassword(getPassword());
+ return pool;
+ }
+
+}
diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java
index 31054186e3..20f030e075 100644
--- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java
+++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java
@@ -20,7 +20,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import org.hibernate.ejb.HibernateEntityManager;
-import org.springframework.bootstrap.autoconfigure.jdbc.EmbeddedDatabaseAutoConfiguration;
+import org.springframework.bootstrap.autoconfigure.jdbc.EmbeddedDatabaseConfiguration;
import org.springframework.bootstrap.context.annotation.ConditionalOnClass;
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
@@ -61,7 +61,7 @@ public class HibernateJpaAutoConfiguration extends JpaAutoConfiguration {
if (isAutoConfiguredDataSource()) {
properties.put("hibernate.hbm2ddl.auto", "create-drop");
String dialect = EMBEDDED_DATABASE_DIALECTS
- .get(EmbeddedDatabaseAutoConfiguration.getEmbeddedDatabaseType());
+ .get(EmbeddedDatabaseConfiguration.getEmbeddedDatabaseType());
if (dialect != null) {
properties.put("hibernate.dialect", dialect);
}
diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/orm/jpa/JpaAutoConfiguration.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/orm/jpa/JpaAutoConfiguration.java
index 02b5bf9ec5..c762a15a23 100644
--- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/orm/jpa/JpaAutoConfiguration.java
+++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/orm/jpa/JpaAutoConfiguration.java
@@ -27,7 +27,7 @@ import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.bootstrap.autoconfigure.jdbc.EmbeddedDatabaseAutoConfiguration;
+import org.springframework.bootstrap.autoconfigure.jdbc.EmbeddedDatabaseConfiguration;
import org.springframework.bootstrap.context.annotation.AutoConfigurationUtils;
import org.springframework.bootstrap.context.annotation.ConditionalOnBean;
import org.springframework.bootstrap.context.annotation.ConditionalOnClass;
@@ -69,14 +69,14 @@ public abstract class JpaAutoConfiguration implements BeanFactoryAware {
/**
* Determines if the {@code dataSource} being used by Spring was created from
- * {@link EmbeddedDatabaseAutoConfiguration}.
+ * {@link EmbeddedDatabaseConfiguration}.
* @return true if the data source was auto-configured.
*/
protected boolean isAutoConfiguredDataSource() {
try {
BeanDefinition beanDefinition = this.beanFactory
.getBeanDefinition("dataSource");
- return EmbeddedDatabaseAutoConfiguration.class.getName().equals(
+ return EmbeddedDatabaseConfiguration.class.getName().equals(
beanDefinition.getFactoryBeanName());
} catch (NoSuchBeanDefinitionException e) {
return false;
diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/web/WebMvcAutoConfiguration.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/web/WebMvcAutoConfiguration.java
index dd2ece7a3a..929cb6ee46 100644
--- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/web/WebMvcAutoConfiguration.java
+++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/web/WebMvcAutoConfiguration.java
@@ -18,9 +18,11 @@ package org.springframework.bootstrap.autoconfigure.web;
import javax.servlet.Servlet;
+import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.bootstrap.autoconfigure.web.WebMvcAutoConfiguration.WebMvcConfiguration;
+import org.springframework.bootstrap.context.annotation.ConditionalOnBean;
import org.springframework.bootstrap.context.annotation.ConditionalOnClass;
import org.springframework.bootstrap.context.annotation.ConditionalOnMissingBean;
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
@@ -31,13 +33,17 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistry;
+import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerMapping;
+import org.springframework.web.servlet.View;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.view.BeanNameViewResolver;
+import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link EnableWebMvc Web MVC}.
@@ -61,6 +67,23 @@ public class WebMvcAutoConfiguration {
@Autowired
private ListableBeanFactory beanFactory;
+ @ConditionalOnBean(View.class)
+ @Bean
+ public BeanNameViewResolver beanNameViewResolver() {
+ BeanNameViewResolver resolver = new BeanNameViewResolver();
+ resolver.setOrder(0);
+ return resolver;
+ }
+
+ @ConditionalOnBean(View.class)
+ @Bean
+ public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
+ ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
+ resolver.setContentNegotiationManager(beanFactory
+ .getBean(ContentNegotiationManager.class));
+ return resolver;
+ }
+
@Bean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/initializer/LoggingInitializer.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/initializer/LoggingInitializer.java
deleted file mode 100644
index 1a22a635c1..0000000000
--- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/initializer/LoggingInitializer.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * 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.bootstrap.context.initializer;
-
-import java.lang.management.ManagementFactory;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.springframework.bootstrap.logging.JavaLoggerConfigurer;
-import org.springframework.bootstrap.logging.LogbackConfigurer;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextInitializer;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.core.Ordered;
-import org.springframework.core.env.ConfigurableEnvironment;
-import org.springframework.core.env.Environment;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.Log4jConfigurer;
-
-/**
- * An {@link ApplicationContextInitializer} that configures a logging framework depending
- * on what it finds on the classpath and in the {@link Environment}. If the environment
- * contains a property logging.config
then that will be used to initialize
- * the logging system, otherwise a default location is used. The classpath is probed for
- * log4j and logback and if those are present they will be reconfigured, otherwise vanilla
- * java.util.logging
will be used.
- *
- *
- * The default config locations are classpath:log4j.properties
or
- * classpath:log4j.xml
for log4j; classpath:logback.xml
for
- * logback; and classpath:logging.properties
for
- * java.util.logging
. If the correct one of those files is not found then
- * some sensible defaults are adopted from files of the same name but in the package
- * containing {@link LoggingInitializer}.
- *
- *
- *
- * Some system properties may be set as side effects, and these can be useful if the
- * logging configuration supports placeholders (i.e. log4j or logback):
- *
- * LOG_FILE
is set to the value of logging.file
if found in
- * the environment
- * LOG_PATH
is set to the value of logging.path
if found in
- * the environment
- * PID
is set to the value of the current process ID if it can be
- * determined
- *
- *
- * @author Dave Syer
- * @author Phillip Webb
- */
-public class LoggingInitializer implements
- ApplicationContextInitializer, Ordered {
-
- private static final Map ENVIRONMENT_SYSTEM_PROPERTY_MAPPING;
- static {
- ENVIRONMENT_SYSTEM_PROPERTY_MAPPING = new HashMap();
- ENVIRONMENT_SYSTEM_PROPERTY_MAPPING.put("logging.file", "LOG_FILE");
- ENVIRONMENT_SYSTEM_PROPERTY_MAPPING.put("logging.path", "LOG_PATH");
- ENVIRONMENT_SYSTEM_PROPERTY_MAPPING.put("PID", "PID");
- }
-
- private int order = Integer.MIN_VALUE + 1;
-
- /**
- * Initialize the logging system according to preferences expressed through the
- * {@link Environment} and the classpath.
- */
- @Override
- public void initialize(ConfigurableApplicationContext applicationContext) {
-
- ConfigurableEnvironment environment = applicationContext.getEnvironment();
-
- for (Map.Entry mapping : ENVIRONMENT_SYSTEM_PROPERTY_MAPPING
- .entrySet()) {
- if (environment.containsProperty(mapping.getKey())) {
- System.setProperty(mapping.getValue(),
- environment.getProperty(mapping.getKey()));
- }
- }
-
- if (System.getProperty("PID") == null) {
- System.setProperty("PID", getPid());
- }
-
- LoggingSystem system = LoggingSystem.get(applicationContext.getClassLoader());
- system.init(applicationContext);
- }
-
- private String getPid() {
- String name = ManagementFactory.getRuntimeMXBean().getName();
- if (name != null) {
- return name.split("@")[0];
- }
- return "????";
- }
-
- public void setOrder(int order) {
- this.order = order;
- }
-
- @Override
- public int getOrder() {
- return this.order;
- }
-
- private static enum LoggingSystem {
-
- /**
- * Log4J
- */
- LOG4J("org.apache.log4j.PropertyConfigurator", "log4j.xml", "log4j.properties") {
-
- @Override
- protected void doInit(ApplicationContext applicationContext,
- String configLocation) throws Exception {
- Log4jConfigurer.initLogging(configLocation);
- }
- },
-
- /**
- * Logback
- */
- LOGBACK("ch.qos.logback.core.Appender", "logback.xml") {
-
- @Override
- protected void doInit(ApplicationContext applicationContext,
- String configLocation) throws Exception {
- LogbackConfigurer.initLogging(configLocation);
- }
- },
-
- /**
- * Java Util Logging
- */
- JAVA(null, "logging.properties") {
-
- @Override
- protected void doInit(ApplicationContext applicationContext,
- String configLocation) throws Exception {
- JavaLoggerConfigurer.initLogging(configLocation);
- }
- };
-
- private final String className;
-
- private final String[] paths;
-
- private LoggingSystem(String className, String... paths) {
- this.className = className;
- this.paths = paths;
- }
-
- public void init(ApplicationContext applicationContext) {
- String configLocation = getConfigLocation(applicationContext);
- try {
- doInit(applicationContext, configLocation);
- } catch (RuntimeException ex) {
- throw ex;
- } catch (Exception ex) {
- throw new IllegalStateException("Cannot initialize logging from "
- + configLocation, ex);
- }
-
- }
-
- protected abstract void doInit(ApplicationContext applicationContext,
- String configLocation) throws Exception;
-
- private String getConfigLocation(ApplicationContext applicationContext) {
- Environment environment = applicationContext.getEnvironment();
- ClassLoader classLoader = applicationContext.getClassLoader();
-
- // User specified config
- if (environment.containsProperty("logging.config")) {
- return environment.getProperty("logging.config");
- }
-
- // Common patterns
- for (String path : this.paths) {
- ClassPathResource resource = new ClassPathResource(path, classLoader);
- if (resource.exists()) {
- return "classpath:" + path;
- }
- }
-
- // Fallback to the default
- String defaultPath = ClassUtils.getPackageName(JavaLoggerConfigurer.class);
- defaultPath = defaultPath.replace(".", "/");
- defaultPath = defaultPath + "/" + this.paths[this.paths.length - 1];
- return "classpath:" + defaultPath;
- }
-
- public static LoggingSystem get(ClassLoader classLoader) {
- for (LoggingSystem loggingSystem : values()) {
- String className = loggingSystem.className;
- if (className == null || ClassUtils.isPresent(className, classLoader)) {
- return loggingSystem;
- }
- }
- return JAVA;
- }
-
- }
-
-}
diff --git a/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/data/JpaRepositoriesAutoConfigurationTests.java b/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/data/JpaRepositoriesAutoConfigurationTests.java
index 2134662cf8..74c35e1619 100644
--- a/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/data/JpaRepositoriesAutoConfigurationTests.java
+++ b/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/data/JpaRepositoriesAutoConfigurationTests.java
@@ -19,7 +19,7 @@ import javax.persistence.EntityManagerFactory;
import org.junit.Test;
import org.springframework.bootstrap.autoconfigure.data.test.CityRepository;
-import org.springframework.bootstrap.autoconfigure.jdbc.EmbeddedDatabaseAutoConfiguration;
+import org.springframework.bootstrap.autoconfigure.jdbc.EmbeddedDatabaseConfiguration;
import org.springframework.bootstrap.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@@ -40,7 +40,7 @@ public class JpaRepositoriesAutoConfigurationTests {
public void testDefaultRepositoryConfiguration() throws Exception {
this.context = new AnnotationConfigApplicationContext();
this.context.register(TestConfiguration.class,
- EmbeddedDatabaseAutoConfiguration.class,
+ EmbeddedDatabaseConfiguration.class,
JpaRepositoriesAutoConfiguration.class,
HibernateJpaAutoConfiguration.class);
this.context.refresh();
diff --git a/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/BasicDataSourceAutoConfigurationTests.java b/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/BasicDataSourceAutoConfigurationTests.java
new file mode 100644
index 0000000000..61621045a1
--- /dev/null
+++ b/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/BasicDataSourceAutoConfigurationTests.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.bootstrap.autoconfigure.jdbc;
+
+import javax.sql.DataSource;
+
+import org.junit.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author Dave Syer
+ *
+ */
+public class BasicDataSourceAutoConfigurationTests {
+
+ private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+
+ @Test
+ public void testDataSourceExists() throws Exception {
+ this.context.register(BasicDataSourceConfiguration.class);
+ this.context.refresh();
+ assertNotNull(this.context.getBean(DataSource.class));
+ }
+
+}
diff --git a/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/DataSourceAutoConfigurationTests.java b/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/DataSourceAutoConfigurationTests.java
new file mode 100644
index 0000000000..733b041ab5
--- /dev/null
+++ b/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/DataSourceAutoConfigurationTests.java
@@ -0,0 +1,88 @@
+/*
+ * 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.bootstrap.autoconfigure.jdbc;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.sql.DataSource;
+
+import org.junit.Test;
+import org.springframework.bootstrap.autoconfigure.PropertyPlaceholderAutoConfiguration;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.core.env.MapPropertySource;
+import org.springframework.jdbc.core.JdbcOperations;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
+import org.springframework.util.ClassUtils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Dave Syer
+ *
+ */
+public class DataSourceAutoConfigurationTests {
+
+ private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+
+ @Test
+ public void testDefaultDataSourceExists() throws Exception {
+ this.context.register(DataSourceAutoConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class);
+ this.context.refresh();
+ assertNotNull(this.context.getBean(DataSource.class));
+ }
+
+ @Test
+ public void testJdbcTemplateExists() throws Exception {
+ this.context.register(DataSourceAutoConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class);
+ this.context.refresh();
+ JdbcTemplate jdbcTemplate = this.context.getBean(JdbcTemplate.class);
+ assertNotNull(jdbcTemplate);
+ assertNotNull(jdbcTemplate.getDataSource());
+ }
+
+ @Test
+ public void testNamedParameterJdbcTemplateExists() throws Exception {
+ this.context.register(DataSourceAutoConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class);
+ this.context.refresh();
+ assertNotNull(this.context.getBean(NamedParameterJdbcOperations.class));
+ }
+
+ @Test
+ public void testDataSourceInitialized() throws Exception {
+ this.context.register(DataSourceAutoConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class);
+ Map map = new HashMap();
+ map.put("spring.database.schema",
+ ClassUtils.addResourcePathToPackagePath(getClass(), "schema.sql"));
+ this.context.getEnvironment().getPropertySources()
+ .addFirst(new MapPropertySource("test", map));
+ this.context.refresh();
+ DataSource dataSource = this.context.getBean(DataSource.class);
+ assertTrue(dataSource instanceof org.apache.tomcat.jdbc.pool.DataSource);
+ assertNotNull(dataSource);
+ JdbcOperations template = new JdbcTemplate(dataSource);
+ assertEquals(new Integer(0),
+ template.queryForObject("SELECT COUNT(*) from FOO", Integer.class));
+ }
+
+}
diff --git a/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseAutoConfigurationTests.java b/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseAutoConfigurationTests.java
new file mode 100644
index 0000000000..e7affd1d01
--- /dev/null
+++ b/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseAutoConfigurationTests.java
@@ -0,0 +1,41 @@
+/*
+ * 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.bootstrap.autoconfigure.jdbc;
+
+import javax.sql.DataSource;
+
+import org.junit.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author Dave Syer
+ *
+ */
+public class EmbeddedDatabaseAutoConfigurationTests {
+
+ private AnnotationConfigApplicationContext context;
+
+ @Test
+ public void testDefaultEmbeddedDatabase() throws Exception {
+ this.context = new AnnotationConfigApplicationContext();
+ this.context.register(EmbeddedDatabaseConfiguration.class);
+ this.context.refresh();
+ assertNotNull(this.context.getBean(DataSource.class));
+ }
+
+}
diff --git a/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/TomcatDataSourceAutoConfigurationTests.java b/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/TomcatDataSourceAutoConfigurationTests.java
new file mode 100644
index 0000000000..ab81405555
--- /dev/null
+++ b/spring-bootstrap/src/test/java/org/springframework/bootstrap/autoconfigure/jdbc/TomcatDataSourceAutoConfigurationTests.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.bootstrap.autoconfigure.jdbc;
+
+import javax.sql.DataSource;
+
+import org.junit.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author Dave Syer
+ *
+ */
+public class TomcatDataSourceAutoConfigurationTests {
+
+ private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+
+ @Test
+ public void testDataSourceExists() throws Exception {
+ this.context.register(TomcatDataSourceConfiguration.class);
+ this.context.refresh();
+ assertNotNull(this.context.getBean(DataSource.class));
+ }
+
+}
diff --git a/spring-bootstrap/src/test/resources/org/springframework/bootstrap/autoconfigure/jdbc/schema.sql b/spring-bootstrap/src/test/resources/org/springframework/bootstrap/autoconfigure/jdbc/schema.sql
new file mode 100644
index 0000000000..38de881057
--- /dev/null
+++ b/spring-bootstrap/src/test/resources/org/springframework/bootstrap/autoconfigure/jdbc/schema.sql
@@ -0,0 +1,4 @@
+CREATE TABLE FOO (
+ id INTEGER IDENTITY PRIMARY KEY,
+ name VARCHAR(30),
+);
\ No newline at end of file