我正在为具有多个数据源的spring boot应用程序创建unittesting。(配置很大程度上受到了这个答案的启发)
@Configuration
public class DatasourceConfig {
@Primary
@Bean
@ConfigurationProperties(prefix = "datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "datasource.primary.liquibase")
public LiquibaseProperties primaryLiquibaseProperties() {
return new LiquibaseProperties();
}
@Bean
public SpringLiquibase primaryLiquibase() {
return springLiquibase(primaryDataSource(), primaryLiquibaseProperties());
}
@Bean
@ConfigurationProperties(prefix = "datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "datasource.secondary.liquibase")
public LiquibaseProperties secondaryLiquibaseProperties() {
return new LiquibaseProperties();
}
@Bean
public SpringLiquibase secondaryLiquibase() {
return springLiquibase(secondaryDataSource(), secondaryLiquibaseProperties());
}
private static SpringLiquibase springLiquibase(DataSource dataSource, LiquibaseProperties properties) {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog(properties.getChangeLog());
liquibase.setContexts(properties.getContexts());
liquibase.setDefaultSchema(properties.getDefaultSchema());
liquibase.setDropFirst(properties.isDropFirst());
liquibase.setShouldRun(properties.isEnabled());
liquibase.setLabels(properties.getLabels());
liquibase.setChangeLogParameters(properties.getParameters());
liquibase.setRollbackFile(properties.getRollbackFile());
return liquibase;
}
...
}
而且
datasource:
primary:
url: jdbc:mysql://localhost/primary
username: username
password: password
liquibase:
change-log: classpath:/db/changelog/db.primary.changelog-master.xml
secondary:
url: jdbc:mysql://localhost/secondary
username: username
password: password
liquibase:
change-log: classpath:/db/changelog/db.secondary.changelog-master.xml
应用程序运行正常。
management:
endpoints.web.exposure.include: "*"
security.enabled: false
spring:
zipkin:
discoveryClientEnabled: false
sender:
type: kafka
#type: web
liquibase:
enabled: false
datasource:
url: "jdbc:h2:mem:testdb"
jdbc-url: "jdbc:h2:mem:testdb"
username: sa
password:
secondary-datasource:
url: "jdbc:h2:mem:testdb"
jdbc-url: "jdbc:h2:mem:testdb"
username: sa
password:
datasource:
primary-liquibase:
liquibase:
url: "jdbc:h2:mem:testdb"
username: sa
password:
secondary-liquibase:
liquibase:
url: "jdbc:h2:mem:testdb"
username: sa
password:
liquibase:
enable: false
package com.foo.bar.car;
import com.foo.bar.car.utils.KSUIDGenerator;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureTestDatabase
// https://stackoverflow.com/a/58786742/1534925
//@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
//@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
class CarApplicationTests {
@Test
public void contextLoads() {
String h = "Hello World!";
Assertions.assertEquals(h, "Hello World!");
}
@Test
public void testKSUIDGeneration() {
Assertions.assertNotNull(KSUIDGenerator.generateKSUID());
}
}
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [liquibase.integration.spring.SpringLiquibase]: Factory method 'primaryLiquibase' threw exception; nested exception is java.lang.IllegalArgumentException: No visible constructors in class org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean
不确定缺少了什么配置更改。
要使其发挥作用,需要做几项调整:
>
在CarApplication.java中排除DB和Liquibase的自动配置
@SpringBootApplication(exclude={DataSourceAutoConfiguration.Class,LiquiBaseAutoConfiguration.Class})
仔细检查下面的设置,以防在上面列出的所有调整后它都不起作用(我改变了这里和那里的东西,我通常的编码方式使它对我来说舒服):
CarApplication.java
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class,
LiquibaseAutoConfiguration.class })
public class CarApplication {
public static void main(String[] args) {
SpringApplication.run(CarApplication.class, args);
}
}
application.yaml
server:
port: 9999
datasource:
url: jdbc:postgresql://localhost:8888/foo
jdbcUrl: jdbc:postgresql://localhost:5432/foo
username: username
password: password
driverClassName: org.postgresql.Driver
liquibase:
change-log: classpath:db-changelog/primary.xml
secondary-datasource:
url: jdbc:postgresql://localhost:8888/bar
jdbcUrl: jdbc:postgresql://localhost:5432/bar
username: username
password: password
driverClassName: org.postgresql.Driver
liquibase:
change-log: classpath:db-changelog/secondary.xml
@Configuration
public class DatabaseConfig {
@Bean
@Primary
@ConfigurationProperties(prefix = "datasource")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "secondary-datasource")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "datasource.liquibase")
public LiquibaseProperties primaryLiquibaseProperties() {
return new LiquibaseProperties();
}
@Bean("liquibase")
public SpringLiquibase primaryLiquibase() {
return springLiquibase(primaryDataSource(), primaryLiquibaseProperties());
}
@Bean
@ConfigurationProperties(prefix = "secondary-datasource.liquibase")
public LiquibaseProperties secondaryLiquibaseProperties() {
return new LiquibaseProperties();
}
@Bean
public SpringLiquibase secondaryLiquibase() {
return springLiquibase(secondaryDataSource(), secondaryLiquibaseProperties());
}
private static SpringLiquibase springLiquibase(DataSource dataSource, LiquibaseProperties properties) {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog(properties.getChangeLog());
liquibase.setContexts(properties.getContexts());
liquibase.setDefaultSchema(properties.getDefaultSchema());
liquibase.setDropFirst(properties.isDropFirst());
liquibase.setShouldRun(properties.isEnabled());
liquibase.setLabels(properties.getLabels());
liquibase.setChangeLogParameters(properties.getParameters());
liquibase.setRollbackFile(properties.getRollbackFile());
return liquibase;
}
}
datasource:
url: "jdbc:h2:mem:testdb"
jdbc-url: "jdbc:h2:mem:testdb"
username: sa
password:
liquibase:
change-log: classpath:db-changelog/primary.xml
secondary-datasource:
url: "jdbc:h2:mem:testdb"
jdbc-url: "jdbc:h2:mem:testdb"
username: sa
password:
liquibase:
change-log: classpath:db-changelog/secondary.xml
@SpringBootTest
class CarApplicationTests {
@Test
public void contextLoads() {
String h = "Hello World!";
Assertions.assertEquals(h, "Hello World!");
}
@Test
public void testKSUIDGeneration() {
Assertions.assertNotNull(KSUIDGenerator.generateKSUID());
}
}
当我试图在spring-boot上使用多个数据源时,我面临着一个巨大的问题。我的问题是因为我正在使用spring batch,而我没有足够的权限在我的生产数据库上从spring-batch创建元数据表,所以我需要使用例如H2来创建这些表,但是当我试图在我的模型中加载一个在我的作业处理器中具有关系为@OneToMany的字段时,我收到了LazyInitializationException Spri
我试着用Twilio发一条短信,如下所示: 我得到以下错误:
我试图创建一个Spring Boot应用程序,它连接两个数据源。我可以通过遵循Spring文档来实现这一点,但我面临的挑战是实现以下目标 null 是否有任何方法可以使用Spring Boot的自动配置功能来实现这一点,或者我必须基于概要文件创建不同的数据源bean。
我有一个简单的SpringBoot应用程序,我想使用AutoConfiguration来配置Tomcat jdbc池数据源。 我正在使用这些Spring依赖项: 以下是我的 application.yml 文件中的数据源属性: 我确定正在加载属性,因为应用程序正在获取其他值。 我在配置文件中将 bean 定义为: 我将数据源注入到我的DAO中,如下所示: 如果我在getDataSource()方法
谢谢,克里斯
我正试图使用INFOQ提供的本教程设置一个包含多个数据源的Springboot(v2.0.0.BUILD-SNAPSHOT)项目 https://www.infoq.com/articles/Multiple-Databases-with-Spring-Boot 但是我需要使用多个EntityManager来代替JdbcTemplate 这是我目前掌握的情况 应用属性 一个pplication.j