如何动态设置 Spring Data Cassandra 键空间?
How to set Spring Data Cassandra keyspace dynamically?
我们使用 Spring Boot 1.5.10 和 Spring Data for Apache Cassandra,一切正常。
我们有一个新的要求,我们需要在服务启动时连接到不同的密钥空间 运行。
通过使用Spring Cloud Config Server,我们可以很方便的设置spring.data.cassandra.keyspace-name
的值,但是不确定有没有办法动态切换(force)如果先使用此新密钥空间而无需重新启动的服务?
有什么想法或建议吗?
是的,您可以在持有 spring.data.cassandra.keyspace-name
值的 bean 上使用 @RefreshScope
注释。
通过 Spring 云配置服务器更改配置值后,您必须在应用程序的 /refresh
端点上发出 POST。
A Spring @Bean that is marked as @RefreshScope will get special treatment when there is a configuration change. This addresses the problem of stateful beans that only get their configuration injected when they are initialized. For instance if a DataSource has open connections when the database URL is changed via the Environment, we probably want the holders of those connections to be able to complete what they are doing. Then the next time someone borrows a connection from the pool he gets one with the new URL.
来自 RefreshScope class javadoc:
A Scope implementation that allows for beans to be refreshed dynamically at runtime (see refresh(String) and refreshAll()). If a bean is refreshed then the next time the bean is accessed (i.e. a method is executed) a new instance is created. All lifecycle methods are applied to the bean instances, so any destruction callbacks that were registered in the bean factory are called when it is refreshed, and then the initialization callbacks are invoked as normal when the new instance is created. A new bean instance is created from the original bean definition, so any externalized content (property placeholders or expressions in string literals) is re-evaluated when it is created.
使用 @RefreshScope
和 properties/repositories 不起作用,因为键空间绑定到 Cassandra Session
bean。
使用 Spring Data Cassandra 1.5 和 Spring Boot 1.5 你至少有两个选择:
- 声明
@RefreshScope
CassandraSessionFactoryBean
,另请参阅 CassandraDataAutoConfiguration
。这将在刷新时中断所有 Cassandra 操作并重新创建所有依赖 bean。
收听 RefreshScopeRefreshedEvent
并通过 USE my-new-keyspace;
更改键空间。这种方法侵入性较小,不会中断 运行 查询。您基本上会使用事件侦听器。
@Component
class MySessionRefresh {
private final Session session;
private final Environment environment;
// omitted constructors for brevity
@EventListener
@Order(Ordered.LOWEST_PRECEDENCE)
public void handle(RefreshScopeRefreshedEvent event) {
String keyspace = environment.getProperty("spring.data.cassandra.keyspace-name");
session.execute("USE " + keyspace + ";");
}
}
在 Spring Data Cassandra 2 中,我们引入了 SessionFactory
abstraction providing AbstractRoutingSessionFactory
用于 CQL/session 调用的代码控制路由。
我们使用 Spring Boot 1.5.10 和 Spring Data for Apache Cassandra,一切正常。
我们有一个新的要求,我们需要在服务启动时连接到不同的密钥空间 运行。
通过使用Spring Cloud Config Server,我们可以很方便的设置spring.data.cassandra.keyspace-name
的值,但是不确定有没有办法动态切换(force)如果先使用此新密钥空间而无需重新启动的服务?
有什么想法或建议吗?
是的,您可以在持有 spring.data.cassandra.keyspace-name
值的 bean 上使用 @RefreshScope
注释。
通过 Spring 云配置服务器更改配置值后,您必须在应用程序的 /refresh
端点上发出 POST。
A Spring @Bean that is marked as @RefreshScope will get special treatment when there is a configuration change. This addresses the problem of stateful beans that only get their configuration injected when they are initialized. For instance if a DataSource has open connections when the database URL is changed via the Environment, we probably want the holders of those connections to be able to complete what they are doing. Then the next time someone borrows a connection from the pool he gets one with the new URL.
来自 RefreshScope class javadoc:
A Scope implementation that allows for beans to be refreshed dynamically at runtime (see refresh(String) and refreshAll()). If a bean is refreshed then the next time the bean is accessed (i.e. a method is executed) a new instance is created. All lifecycle methods are applied to the bean instances, so any destruction callbacks that were registered in the bean factory are called when it is refreshed, and then the initialization callbacks are invoked as normal when the new instance is created. A new bean instance is created from the original bean definition, so any externalized content (property placeholders or expressions in string literals) is re-evaluated when it is created.
使用 @RefreshScope
和 properties/repositories 不起作用,因为键空间绑定到 Cassandra Session
bean。
使用 Spring Data Cassandra 1.5 和 Spring Boot 1.5 你至少有两个选择:
- 声明
@RefreshScope
CassandraSessionFactoryBean
,另请参阅CassandraDataAutoConfiguration
。这将在刷新时中断所有 Cassandra 操作并重新创建所有依赖 bean。 收听
RefreshScopeRefreshedEvent
并通过USE my-new-keyspace;
更改键空间。这种方法侵入性较小,不会中断 运行 查询。您基本上会使用事件侦听器。@Component class MySessionRefresh { private final Session session; private final Environment environment; // omitted constructors for brevity @EventListener @Order(Ordered.LOWEST_PRECEDENCE) public void handle(RefreshScopeRefreshedEvent event) { String keyspace = environment.getProperty("spring.data.cassandra.keyspace-name"); session.execute("USE " + keyspace + ";"); } }
在 Spring Data Cassandra 2 中,我们引入了 SessionFactory
abstraction providing AbstractRoutingSessionFactory
用于 CQL/session 调用的代码控制路由。