Spring Data Cassandra配置动态更改

时间:2018-10-25 22:38:01

标签: java spring spring-boot cassandra spring-data-cassandra

我正在尝试对我的应用程序执行类似的操作。我正在使用以下版本的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一起使用时是否有一些准则?如果有人早些做过,您可以分享吗?

1 个答案:

答案 0 :(得分:0)

您在这里混合了几件事。

  1. 该配置包含属性和bean定义。
  2. @RefreshScope上的
  3. AppConfig对Spring Boot的自动配置造成一些干扰,并且不使用声明的Bean(这就是为什么看到Parameter 2 of constructor…的原因)。

为了进行清理,我们将尽可能地重复使用Spring Boot提供的内容,并且声明真正需要的内容。

请按照以下步骤解决此问题(基于上面的代码):

  1. 创建一个@ConfigurationProperties bean来封装您的属性,或者更好的是,重用CassandraProperties
  2. 重新启用CassandraAutoConfiguration并删除自己的MappingContextCassandraConverter bean,仅保留ClusterSession bean定义
  3. 根据需要声明ClusterSession 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());
    }
}