[bs-127] Add DataSourceTransactionManager if no others are in use

* If the auto config class has a high Order it can check for
an existing transaction manager
* Unit tests added, and checked also witrh petclinic

[Fixes #50064347]
This commit is contained in:
Dave Syer 2013-05-18 16:18:34 +01:00
parent 8dae41f24c
commit ab121dc91b
7 changed files with 234 additions and 65 deletions

View File

@ -95,16 +95,6 @@
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-javaconfig</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.23</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -1,55 +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.sample.service;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
/**
* @author Dave Syer
*
*/
@Configuration
@Profile("prod")
public class ProductionDatabase {
@Value("${spring.database.driverClassName:com.mysql.jdbc.Driver}")
private String driverClassName;
@Value("${spring.database.url:jdbc:mysql://localhost:3306/test}")
private String url;
@Value("${spring.database.username:root}")
private String username;
@Value("${spring.database.password:}")
private String password;
@Bean
public DataSource dataSource() {
org.apache.tomcat.jdbc.pool.DataSource pool = new org.apache.tomcat.jdbc.pool.DataSource();
pool.setDriverClassName(this.driverClassName);
pool.setUrl(this.url);
pool.setUsername(this.username);
pool.setPassword(this.password);
return pool;
}
}

View File

@ -0,0 +1,54 @@
/*
* 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.beans.factory.annotation.Autowired;
import org.springframework.bootstrap.context.annotation.ConditionalOnBean;
import org.springframework.bootstrap.context.annotation.ConditionalOnClass;
import org.springframework.bootstrap.context.annotation.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
/**
* @author Dave Syer
*
*/
@Configuration
@ConditionalOnClass({ JdbcTemplate.class, PlatformTransactionManager.class })
public class DataSourceTransactionManagerAutoConfiguration implements Ordered {
@Override
public int getOrder() {
return Integer.MAX_VALUE;
}
@Autowired(required = false)
private DataSource dataSource;
@Bean
@ConditionalOnMissingBean(name = "transactionManager")
@ConditionalOnBean(DataSource.class)
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(this.dataSource);
}
}

View File

@ -4,6 +4,7 @@ org.springframework.bootstrap.autoconfigure.MessageSourceAutoConfiguration,\
org.springframework.bootstrap.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.bootstrap.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.bootstrap.autoconfigure.data.JpaRepositoriesAutoConfiguration,\
org.springframework.bootstrap.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.bootstrap.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.bootstrap.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.bootstrap.autoconfigure.web.EmbeddedContainerCustomizerConfiguration,\

View File

@ -0,0 +1,54 @@
/*
* 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 org.springframework.jdbc.datasource.DataSourceTransactionManager;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* @author Dave Syer
*
*/
public class DataSourceTransactionManagerAutoConfigurationTests {
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@Test
public void testDataSourceExists() throws Exception {
this.context.register(EmbeddedDatabaseConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(DataSource.class));
assertNotNull(this.context.getBean(DataSourceTransactionManager.class));
}
@Test
public void testNoDataSourceExists() throws Exception {
this.context.register(DataSourceTransactionManagerAutoConfiguration.class);
this.context.refresh();
assertEquals(0, this.context.getBeanNamesForType(DataSource.class).length);
assertEquals(
0,
this.context.getBeanNamesForType(DataSourceTransactionManager.class).length);
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.orm.jpa;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.bootstrap.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.bootstrap.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.bootstrap.autoconfigure.jdbc.EmbeddedDatabaseConfiguration;
import org.springframework.bootstrap.autoconfigure.orm.jpa.test.City;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.orm.jpa.JpaTransactionManager;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
* @author Dave Syer
*
*/
public class HibernateJpaAutoConfigurationTests {
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@Test
public void testEntityManagerCreated() throws Exception {
this.context.register(EmbeddedDatabaseConfiguration.class,
HibernateJpaAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(DataSource.class));
assertNotNull(this.context.getBean(JpaTransactionManager.class));
}
@Test
public void testDataSourceTransactionManagerNotCreated() throws Exception {
this.context.register(EmbeddedDatabaseConfiguration.class,
HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class);
this.context.refresh();
assertNotNull(this.context.getBean(DataSource.class));
assertTrue(this.context.getBean("transactionManager") instanceof JpaTransactionManager);
}
@ComponentScan(basePackageClasses = { City.class })
protected static class TestConfiguration {
}
}

View File

@ -0,0 +1,60 @@
package org.springframework.bootstrap.autoconfigure.orm.jpa.test;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class City implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String state;
@Column(nullable = false)
private String country;
@Column(nullable = false)
private String map;
protected City() {
}
public City(String name, String country) {
super();
this.name = name;
this.country = country;
}
public String getName() {
return this.name;
}
public String getState() {
return this.state;
}
public String getCountry() {
return this.country;
}
public String getMap() {
return this.map;
}
@Override
public String toString() {
return getName() + "," + getState() + "," + getCountry();
}
}