在 Redis 或数据库中存储会话详细信息通常是一个很好的方案。spring-session-jdbc 的默认实现也是使用主数据源来存储和检索会话相关表中的数据。但是当数据库有大量与会话相关的操作时,这可能是一个问题。
为避免这些情况,最好将与会话相关的模式移动到单独的数据库中。在这个例子中,我们将看到如何使用两个独立的数据库,一个用于存储应用程序数据,一个用于存储会话信息。
在这之前,我希望您先了解一下使用 Spring session 的JDBC ,以及如何实现 JDBC 会话存储的一些背景知识。
我们可以为与会话相关的自动配置提供数据源的最简单方法是定义一个带有 @SpringSessionDataSource
注释的 DataSource
bean。起初,这似乎很容易,但事实并非如此。当您定义自己的 DataSource
bean 时,它会弄乱默认的自动装配。要安全地提供第二个数据源,您需要遵循这些说明。
首先,为每个数据库创建两组属性。在我的例子中,我在演示中使用了两个独立的内存中 h2 数据库。
debug=true
# Properties for primary database
spring.datasource.url=jdbc:h2:mem:test
spring.datasource.username=root
spring.datasource.password=root
spring.h2.console.enabled=true
# Properties for session database
session.datasource.url=jdbc:h2:mem:sessions
session.datasource.username=sessions
session.datasource.password=sessions
然后使用 DataSourceProperties
属性手动创建这两个数据源。 spring.datasource
配置将用于创建主数据源。 session.datasource
属性将用于创建会话数据源。
@Configuration
public class DataSourceConfig {
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
@Qualifier("dataSource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
public DataSource primaryDataSource(@Qualifier("dataSource") DataSourceProperties dataSourceProperties) {
return dataSourceProperties
.initializeDataSourceBuilder()
.type(HikariDataSource.class)
.build();
}
@Bean
@ConfigurationProperties("session.datasource")
@Qualifier("sessionDataSourceProperties")
public DataSourceProperties sessionDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Qualifier("sessionDataSource")
@SpringSessionDataSource
public DataSource sessionDataSource(@Qualifier("sessionDataSourceProperties") DataSourceProperties sessionDataSourceProperties) {
return sessionDataSourceProperties
.initializeDataSourceBuilder()
.type(HikariDataSource.class)
.build();
}
}
在上面的配置类中,请注意我如何将 sessionDataSource
标记为 @SpringSessionDataSource
。此外,我已经确保数据源及其属性都可以通过使用 @Qualifier
的名称来区分。
如果您使用的是 Oracle 或 MySQL 之类的数据库,那么您已经完成了。在 sessionDataSource
指向的数据库中创建会话相关表 (SPRING_SESSION
,SPRING_SESSION_ATTRIBUTES
),一切顺利。但是如果你想使用这个演示中的嵌入式数据源,或者如果你将 spring.session.jdbc.initialize-schema
设置为 always
,那么你就有问题了。
默认自动配置不知道要为 JdbcSessionDataSourceInitializer
自动装配哪个数据源。因此它最终可能会在主数据源中创建会话表。为避免这种情况,您需要提供自己的 JdbcSessionDataSourceInitializer
bean,如下所示。
@Configuration
@EnableConfigurationProperties(JdbcSessionProperties.class)
public class JdbcSessionConfig {
@Bean
public JdbcSessionDataSourceInitializer
jdbcSessionDataSourceInitializer(@Qualifier("sessionDataSource") DataSource sessionDataSource,
ResourceLoader resourceLoader,
JdbcSessionProperties properties) {
return new JdbcSessionDataSourceInitializer(sessionDataSource, resourceLoader, properties);
}
}
在上面的配置中,请注意我如何使用 @Qualifier
加载 sessionDataSource
。另外,请注意,您需要 EnableConfigurationProperties
才能自动装配 JdbcSessionProperties
。
如果我们做对了这一切,你可以看到会话数据库有两个表,主数据库将被应用程序使用。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://springhow.com/spring-session-different-database/
内容来源于网络,如有侵权,请联系作者删除!