我一直在整理应该是Web应用程序的一个非常常见的用例。我有一个使用REST信息库,JPA等的Spring-Boot应用程序。问题是我有两个数据源:
因为第二个数据源是特定于已验证用户的,所以我尝试使用AbstractRoutingDataSource根据验证后的主要用户路由到正确的数据源。
绝对让我抓狂的是,Spring- Boot正在与我搏斗,以在启动时实例化此数据源。我已经尝试了所有我能想到的东西,包括Lazy和Scope批注。如果我使用Session作用域,则应用程序将引发有关启动时不存在任何会话的错误。@Lazy似乎根本没有帮助。无论我使用什么注释,该数据库都是在Spring Boot启动时实例化的,并且找不到任何导致整个应用程序崩溃的查找键。
另一个问题是,Rest Repository API具有IMO指定指定要使用的实际数据源的可怕方法。如果使用Spring Boot有多个数据源,则必须弄混Qualifier批注,这是运行时调试的噩梦。
任何建议将不胜感激。
您的问题与身份验证管理器配置有关。所有示例和指南都将其设置在中GlobalAuthenticationConfigurerAdapter,例如,它看起来像是您的内部类SimpleEmbeddedSecurityConfiguration:
GlobalAuthenticationConfigurerAdapter
SimpleEmbeddedSecurityConfiguration
@Configuration public static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter { @Bean(name = Global.AUTHENTICATION_DATA_QUALIFIER + "DataSource") public DataSource dataSource() { return new EmbeddedDatabaseBuilder().setName("authdb").setType(EmbeddedDatabaseType.H2).addScripts("security/schema.sql", "security/data.sql").build(); } @Override public void init(AuthenticationManagerBuilder auth) throws Exception { auth.jdbcAuthentication().dataSource(dataSource()).passwordEncoder(passwordEncoder()); } }
如果您不使用,GlobalAuthenticationConfigurerAdapter那么DataSource在创建安全性过滤器时(@Primary DataSource甚至在bean尚未注册之前),Spring Data REST就会获取这些获取的内容,并且整个JPA初始化会非常早地开始(不好的主意)。
DataSource
@Primary
更新:身份验证管理器不是唯一的问题。如果您需要进行会话范围的操作@Primary DataSource(我会说这很不寻常),则需要在启动时关闭所有需要访问数据库的内容(Hibernate和Spring Boot在各个地方)。例:
spring.datasource.initialize: false spring.jpa.hibernate.ddlAuto: none spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults: false spring.jpa.properties.hibernate.dialect: H2
进一步更新:如果您使用的是执行器,它还希望在启动时将主要数据源用于运行状况指示器。您可以通过私有相同类型的bean来覆盖它,例如
@Bean @Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS) @Lazy public DataSourcePublicMetrics dataSourcePublicMetrics() { return new DataSourcePublicMetrics(); }
PS我相信GlobalAuthenticationConfigurerAdapter在Spring Boot 1.2.2中可能并不需要,但在1.2.1或1.1.10中是必需的。