我正在尝试对我的应用程序执行类似的操作。我正在使用以下版本的Spring Boot和Cassandra:
spring-data-cassandra-2.0.8.RELEASE spring-boot-starter-parent-2.0.4.RELEASE 我需要即时更改Cassandra的某些属性(主要是主机名),并希望它与应用程序建立新连接。对于配置更改,我们具有内部的“云配置更改管理”,它可以很好地运行更改并进行监听。 这是我的课程:
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
@RefreshScope
@EnableCassandraRepositories(basePackages = {"com.*.*.*.dao.repo"})
public class AppConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(AppConfig.class);
@Value("${application['cassandraPort']}")
private String cassandraPort;
@Value("${application['cassandraEndpoint']}")
private String cassandraEndpoint;
@Value("${application['keyspaceName']}")
private String keyspaceName;
@Value("${application['cassandraConsistency']}")
private String cassandraConsistency;
@Value("${application['cassandraUserName']}")
private String cassandraUserName;
@Autowired
private AppConfig appConfig;
public AppConfig() {
System.out.println("AppConfig Constructor");
}
public String getCassandraPort() {
return cassandraPort;
}
public void setCassandraPort(String cassandraPort) {
this.cassandraPort = cassandraPort;
}
public String getCassandraEndpoint() {
return cassandraEndpoint;
}
public void setCassandraEndpoint(String cassandraEndpoint) {
this.cassandraEndpoint = cassandraEndpoint;
}
public String getKeyspaceName() {
return keyspaceName;
}
public void setKeyspaceName(String keyspaceName) {
this.keyspaceName = keyspaceName;
}
public String getCassandraConsistency() {
return cassandraConsistency;
}
public void setCassandraConsistency(String cassandraConsistency) {
this.cassandraConsistency = cassandraConsistency;
}
public String getCassandraUserName() {
return cassandraUserName;
}
public void setCassandraUserName(String cassandraUserName) {
this.cassandraUserName = cassandraUserName;
}
@Bean
// @RefreshScope
public CassandraConverter converter() {
return new MappingCassandraConverter(this.mappingContext());
}
@Bean
// @RefreshScope
public CassandraMappingContext mappingContext() {
return new CassandraMappingContext();
}
@Bean
//@RefreshScope
public CassandraSessionFactoryBean session() {
CassandraSessionFactoryBean session = new CassandraSessionFactoryBean();
session.setCluster(this.cluster().getObject());
session.setKeyspaceName(appConfig.getKeyspaceName());
session.setConverter(this.converter());
session.setSchemaAction(SchemaAction.NONE);
return session;
}
@Bean
//@RefreshScope
public CassandraClusterFactoryBean cluster() {
CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
cluster.setContactPoints(appConfig.getCassandraEndpoint());
cluster.setPort(Integer.valueOf(appConfig.getCassandraPort()));
cluster.setUsername(appConfig.getCassandraUserName());
cluster.setPassword("password");
cluster.setQueryOptions(new QueryOptions().setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM));
return cluster;
}
}
但是,当我尝试将@RefreshScope与该Configuration类一起使用时,该应用程序无法启动。这就是控制台中显示的内容:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 2 of constructor in org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration required a bean of type 'com.datastax.driver.core.Cluster' that could not be found.
- Bean method 'cassandraCluster' not loaded because auto-configuration 'CassandraAutoConfiguration' was excluded
Action:
Consider revisiting the entries above or defining a bean of type 'com.datastax.driver.core.Cluster' in your configuration.
在将@RefreshScope与Cassandra Bean一起使用时是否有一些准则?如果有人早些做过,您可以分享吗?
答案 0 :(得分:0)
您在这里混合了几件事。
@RefreshScope
上的AppConfig
对Spring Boot的自动配置造成一些干扰,并且不使用声明的Bean(这就是为什么看到Parameter 2 of constructor…
的原因)。为了进行清理,我们将尽可能地重复使用Spring Boot提供的内容,并且仅声明真正需要的内容。
请按照以下步骤解决此问题(基于上面的代码):
@ConfigurationProperties
bean来封装您的属性,或者更好的是,重用CassandraProperties
。CassandraAutoConfiguration
并删除自己的MappingContext
和CassandraConverter
bean,仅保留Cluster
和Session
bean定义Cluster
和Session
bean,并使其使用@RefreshScope
。您的@Configuration
类应如下所示:示例配置:
@Configuration
public class MyConfig {
@Bean(destroyMethod = "close")
@RefreshScope
public Cluster cassandraCluster(CassandraProperties properties) {
Cluster.Builder builder = Cluster.builder().addContactPoints(properties.getContactPoints().toArray(new String[0]))
.withoutJMXReporting();
return builder.build();
}
@Bean(destroyMethod = "close")
@RefreshScope
public Session cassandraSession(CassandraProperties properties, Cluster cluster) {
return cluster.connect(properties.getKeyspaceName());
}
}