我有一个实现了休眠多租户的Springboot项目,我有几个来自REST端点的数据源,但是我看到Springboot在启动时调用方法selectAnyDataSource(),如果该特定条目的值不正确,则引导程序将失败,我试图添加异常处理,但代码从未通过我的catch块或使用Controller注释的类中的ExceptionHandler注释的方法。
我已经尝试用所有Exception类层次结构声明用ExceptionHandler注释的catch和方法,并在其上设置一个断点,但是代码从未经过它们。
这是我的配置类:
@Configuration
@EnableConfigurationProperties({ JpaProperties.class })
@EnableTransactionManagement(proxyTargetClass=true)
@EnableJpaRepositories(basePackages= {"com.intraway.qx.schedule.model.repository"},transactionManagerRef="transactionManager")
public class MultiTenantJpaConfiguration {
private final DataSourceProperties properties;
private final JpaProperties jpaProperties;
@Value("${getDataSourcesEndpoint}")
private String DataSourceEndpoint;
@Autowired
public MultiTenantJpaConfiguration(DataSourceProperties properties, JpaProperties jpaProperties) {
this.properties = properties;
this.jpaProperties = jpaProperties;
}
@Bean
public MultiTenantConnectionProvider multiTenantConnectionProvider() {
return new DataSourceBasedMultiTenantConnectionProviderImpl();
}
@Bean
public CurrentTenantIdentifierResolver currentTenantIdentifierResolver() {
return new CurrentTenantIdentifierResolverImpl();
}
@Bean(name = "mars2DataSources" )
public Map<String, DataSource> mars2DataSources() {
Map<String, DataSource> datasources = new HashMap<>();
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<BmonitorDataSource[]> responseEntity = restTemplate.getForEntity(DataSourceEndpoint, BmonitorDataSource[].class);
BmonitorDataSource[] bmonitorDataSources = responseEntity.getBody();
for (BmonitorDataSource bmonitorDataSource : bmonitorDataSources) {
String tenantId = bmonitorDataSource.getTenantId();
datasources.put(tenantId,
DataSourceBuilder.create(this.getClass().getClassLoader())
.driverClassName(properties.getDriverClassName())
.url("jdbc:mysql://localhost:" +bmonitorDataSource.getDbPort() +"/" + bmonitorDataSource.getDbSchemaName() + "?useSSL=false")
.username(bmonitorDataSource.getDataSourceUsername())
.password(bmonitorDataSource.getDataSourcePassword())
.build()
);
}
return datasources;
}
@PersistenceContext @Primary @Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(MultiTenantConnectionProvider multiTenantConnectionProvider,
CurrentTenantIdentifierResolver currentTenantIdentifierResolver) {
Map<String, Object> hibernateProps = new LinkedHashMap<>();
hibernateProps.putAll(this.jpaProperties.getProperties());
hibernateProps.put(Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
hibernateProps.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProvider);
hibernateProps.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver);
hibernateProps.put(Environment.AUTOCOMMIT, false);
hibernateProps.put("org.hibernate.FlushMode", "manual");
// No dataSource is set to resulting entityManagerFactoryBean
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setPackagesToScan(new String[] { BmonitorDataSource.class.getPackage().getName() });
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
em.setJpaPropertyMap(hibernateProps);
return em;
}
@Bean
public EntityManagerFactory entityManagerFactory(LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) {
return entityManagerFactoryBean.getObject();
}
@Bean(name="transactionManager")
public PlatformTransactionManager txManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager jpa = new JpaTransactionManager ();
jpa.setEntityManagerFactory(entityManagerFactory);
return jpa;
}
public class DataSourceBasedMultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
private static final long serialVersionUID = 1L;
@Autowired
private Map<String,DataSource> mars2DataSources;
@Bean
@Override
public DataSource selectAnyDataSource() {
try {
return this.mars2DataSources.values().iterator().next();
}
catch (Throwable ex) {
return this.mars2DataSources.values().iterator().next();
}
}
@Override
public DataSource selectDataSource(String tenantId) {
return this.mars2DataSources.get(tenantId);
}
}
我需要,如果由于某种原因,我尝试连接的数据库不可用,我可以处理异常,并且应用程序可以正常工作。