1

我需要在不重新启动应用程序的情况下动态连接到新的 Cassandra 集群。我正在使用 Spring Data Cassandra。

以下代码执行此操作,但由于它不是通过 bean 和 IoC 完成的,因此它不使用ExceptionTranslator将 Cassandra 异常转换为 Spring 可移植DataAccessException层次结构中的异常的实现。

  CqlSession session = CqlSession.builder()
                         .withKeyspace("composite")
                         .build();
  template = new CassandraTemplate(session);

有没有办法通过在正在运行的应用程序中间创建 bean 来动态地使用 Spring Data 连接到 Cassandra,以便我们获得标准异常翻译器的优势?即不使用仅在启动时起作用的注释或 XML。

你能指点我一些示例代码吗?


我正在构建一个服务,所以我真正想要的是让这些新 bean 成为 ApplicationContext 的一部分。我相信上面的代码创建了一个单独的上下文。下面在 ApplicationContext 中创建这些 bean。

        var factory = context.getAutowireCapableBeanFactory();
        var registry = (BeanDefinitionRegistry) factory;
        
        var beanDef = new GenericBeanDefinition();
        beanDef.setBeanClass(Config.class);
        registry.registerBeanDefinition("config", beanDef);

        beanDef = new GenericBeanDefinition();
        beanDef.setBeanClass(CqlSessionFactoryBean.class);
        beanDef.setParentName("config");
        var properties = new MutablePropertyValues();
        properties.add("contactPoints", contactPoints);
        properties.add("keyspaceName", keyspaceName);
        properties.add("localDatacenter", datacenter);
        beanDef.setPropertyValues(properties);
        registry.registerBeanDefinition("session", beanDef);

        beanDef = new GenericBeanDefinition();
        beanDef.setBeanClass(CassandraMappingContext.class);
        beanDef.setParentName("config");
        properties = new MutablePropertyValues();
        var session = factory.getBean("session");
        properties.add("userTypeResolver", new SimpleUserTypeResolver((CqlSession) factory.getBean("session")));
        beanDef.setPropertyValues(properties);
        registry.registerBeanDefinition("mappingContext", beanDef);

        beanDef = new GenericBeanDefinition();
        beanDef.setBeanClass(MappingCassandraConverter.class);
        beanDef.setParentName("config");
        var args = new ConstructorArgumentValues();
        args.addGenericArgumentValue(factory.getBean("mappingContext"));
        beanDef.setConstructorArgumentValues(args);
        registry.registerBeanDefinition("converter", beanDef);

        beanDef = new GenericBeanDefinition();
        beanDef.setBeanClass(SessionFactoryFactoryBean.class);
        beanDef.setParentName("config");
        properties = new MutablePropertyValues();
        properties.add("session", factory.getBean("session"));
        properties.add("converter", factory.getBean("converter"));
        properties.add("schemaAction", SchemaAction.NONE);
        beanDef.setPropertyValues(properties);
        registry.registerBeanDefinition("sessionFactory", beanDef);

        beanDef = new GenericBeanDefinition();
        beanDef.setBeanClass(CassandraTemplate.class);
        beanDef.setParentName("config");
        args = new ConstructorArgumentValues();
        args.addIndexedArgumentValue(0, factory.getBean("sessionFactory"));
        args.addIndexedArgumentValue(1, factory.getBean("converter"));
        beanDef.setConstructorArgumentValues(args);
        registry.registerBeanDefinition("cassandraTemplate", beanDef);
        
        template = (CassandraTemplate) factory.getBean("cassandraTemplate");
4

0 回答 0