Spring 启动多模块项目多数据源
Spring boot Multi-module project multi-datasource
我正在尝试开发具有多数据源连接的多模块 spring 引导项目。我将这个项目分成 5 个模块:
-springboot-multiple-maven-modules:
1.域-> database2的模型
2. domain2 -> database2的模型
3.持久化->database1的持久化
4. persistence2 -> database2的持久化
5. web -> 访问数据库1和数据库2
您可以在下面link下载代码:
GitHub Project
我以这种方式配置了两个数据源:
- 数据库 1:
package rc.persistence;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "hotelEntityManagerFactory", transactionManagerRef = "hotelTransactionManager", basePackages = {
"rc.repository" }) //Mirar si se puede sustituir por rc.domain o rc.repository
public class HotelDbConfig {
@Autowired
private Environment env;
@Bean(name = "hotelDataSource")
@ConfigurationProperties(prefix = "hoteles.datasource")
public DataSource customDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("hoteles.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("hoteles.datasource.url"));
dataSource.setUsername(env.getProperty("hoteles.datasource.username"));
dataSource.setPassword(env.getProperty("hoteles.datasource.password"));
return dataSource;
}
@Bean(name = "hotelEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
@Qualifier("hotelDataSource") DataSource dataSource) {
return builder.dataSource(dataSource).packages("rc.domain")
.persistenceUnit("hotel").build();
}
@Bean(name = "hotelTransactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("hotelEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
- 数据库2:
package rc.persistence2;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "cocheEntityManagerFactory", transactionManagerRef = "cocheTransactionManager", basePackages = {
"rc.repository2" })
public class CocheDbConfig {
@Autowired
private Environment env;
@Primary
@Bean(name = "cocheDataSource")
@ConfigurationProperties(prefix = "coches.datasource")
public DataSource customDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("coches.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("coches.datasource.url"));
dataSource.setUsername(env.getProperty("coches.datasource.username"));
dataSource.setPassword(env.getProperty("coches.datasource.password"));
return dataSource;
}
@Primary
@Bean(name = "cocheEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
@Qualifier("cocheDataSource") DataSource dataSource) {
return builder.dataSource(dataSource).packages("rc.domain2")
.persistenceUnit("coche").build();
}
@Primary
@Bean(name = "cocheTransactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("cocheEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
但是当我尝试使用来自网络模块的存储库时:
package rc.web;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import rc.domain2.Coche;
import rc.persistence2.CocheRepository;
@RestController
public class CocheController {
@Autowired
private CocheRepository cocheRepository;
public CocheController(CocheRepository cocheRepository) {
this.cocheRepository = cocheRepository;
}
@GetMapping(value = "/coches")
public List<Coche> getCoches() {
List<Coche> hotels = this.cocheRepository.findAll();
return hotels;
}
}
它向我显示以下错误:
我尝试了不同的可能性,但结果总是一样的:
2018-09-27 17:08:58.399 WARN 15272 --- [ main]
ConfigServletWebServerApplicationContext : Exception encountered
during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'cocheController' defined in file
[C:\springboot-multiple-maven-modules\web\target\classes\rc\web\CocheController.class]:
Unsatisfied dependency expressed through constructor parameter 0;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'rc.persistence2.CocheRepository' available:
expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {} 2018-09-27 17:08:58.399 INFO 15272 --- [
main] j.LocalContainerEntityManagerFactoryBean : Closing JPA
EntityManagerFactory for persistence unit 'coche' 2018-09-27
17:08:58.400 INFO 15272 --- [ main]
j.LocalContainerEntityManagerFactoryBean : Closing JPA
EntityManagerFactory for persistence unit 'hotel' 2018-09-27
17:08:58.403 INFO 15272 --- [ main]
o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2018-09-27 17:08:58.421 INFO 15272 --- [ main]
ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report
re-run your application with 'debug' enabled. 2018-09-27 17:08:58.670
ERROR 15272 --- [ main]
o.s.b.d.LoggingFailureAnalysisReporter :
*************************** APPLICATION FAILED TO START
Description:
Parameter 0 of constructor in rc.web.CocheController required a bean
of type 'rc.persistence2.CocheRepository' that could not be found.
Action:
Consider defining a bean of type 'rc.persistence2.CocheRepository' in
your configuration.
请帮忙!!
提前致谢!
您在数据源配置中遇到错误。您的 CocheDbConfig 数据源正在扫描基础包 "rc.repository2" 以查找存储库 class,因此它无法在您的控制器中找到 bean 'rc.persistence2.CocheRepository'。
您应该像这样更改 database2 数据源中的基础包
@EnableJpaRepositories(entityManagerFactoryRef = "cocheEntityManagerFactory", transactionManagerRef = "cocheTransactionManager", basePackages = {
"rc.persistence2" })
我正在尝试开发具有多数据源连接的多模块 spring 引导项目。我将这个项目分成 5 个模块: -springboot-multiple-maven-modules: 1.域-> database2的模型 2. domain2 -> database2的模型 3.持久化->database1的持久化 4. persistence2 -> database2的持久化 5. web -> 访问数据库1和数据库2
您可以在下面link下载代码: GitHub Project
我以这种方式配置了两个数据源: - 数据库 1:
package rc.persistence;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "hotelEntityManagerFactory", transactionManagerRef = "hotelTransactionManager", basePackages = {
"rc.repository" }) //Mirar si se puede sustituir por rc.domain o rc.repository
public class HotelDbConfig {
@Autowired
private Environment env;
@Bean(name = "hotelDataSource")
@ConfigurationProperties(prefix = "hoteles.datasource")
public DataSource customDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("hoteles.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("hoteles.datasource.url"));
dataSource.setUsername(env.getProperty("hoteles.datasource.username"));
dataSource.setPassword(env.getProperty("hoteles.datasource.password"));
return dataSource;
}
@Bean(name = "hotelEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
@Qualifier("hotelDataSource") DataSource dataSource) {
return builder.dataSource(dataSource).packages("rc.domain")
.persistenceUnit("hotel").build();
}
@Bean(name = "hotelTransactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("hotelEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
- 数据库2:
package rc.persistence2;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "cocheEntityManagerFactory", transactionManagerRef = "cocheTransactionManager", basePackages = {
"rc.repository2" })
public class CocheDbConfig {
@Autowired
private Environment env;
@Primary
@Bean(name = "cocheDataSource")
@ConfigurationProperties(prefix = "coches.datasource")
public DataSource customDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("coches.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("coches.datasource.url"));
dataSource.setUsername(env.getProperty("coches.datasource.username"));
dataSource.setPassword(env.getProperty("coches.datasource.password"));
return dataSource;
}
@Primary
@Bean(name = "cocheEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
@Qualifier("cocheDataSource") DataSource dataSource) {
return builder.dataSource(dataSource).packages("rc.domain2")
.persistenceUnit("coche").build();
}
@Primary
@Bean(name = "cocheTransactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("cocheEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
但是当我尝试使用来自网络模块的存储库时:
package rc.web;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import rc.domain2.Coche;
import rc.persistence2.CocheRepository;
@RestController
public class CocheController {
@Autowired
private CocheRepository cocheRepository;
public CocheController(CocheRepository cocheRepository) {
this.cocheRepository = cocheRepository;
}
@GetMapping(value = "/coches")
public List<Coche> getCoches() {
List<Coche> hotels = this.cocheRepository.findAll();
return hotels;
}
}
它向我显示以下错误:
我尝试了不同的可能性,但结果总是一样的:
2018-09-27 17:08:58.399 WARN 15272 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cocheController' defined in file [C:\springboot-multiple-maven-modules\web\target\classes\rc\web\CocheController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'rc.persistence2.CocheRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {} 2018-09-27 17:08:58.399 INFO 15272 --- [
main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'coche' 2018-09-27 17:08:58.400 INFO 15272 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'hotel' 2018-09-27 17:08:58.403 INFO 15272 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat] 2018-09-27 17:08:58.421 INFO 15272 --- [ main] ConditionEvaluationReportLoggingListener :Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2018-09-27 17:08:58.670 ERROR 15272 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
*************************** APPLICATION FAILED TO START
Description:
Parameter 0 of constructor in rc.web.CocheController required a bean of type 'rc.persistence2.CocheRepository' that could not be found.
Action:
Consider defining a bean of type 'rc.persistence2.CocheRepository' in your configuration.
请帮忙!!
提前致谢!
您在数据源配置中遇到错误。您的 CocheDbConfig 数据源正在扫描基础包 "rc.repository2" 以查找存储库 class,因此它无法在您的控制器中找到 bean 'rc.persistence2.CocheRepository'。
您应该像这样更改 database2 数据源中的基础包
@EnableJpaRepositories(entityManagerFactoryRef = "cocheEntityManagerFactory", transactionManagerRef = "cocheTransactionManager", basePackages = {
"rc.persistence2" })