我需要在不重新启动应用程序的情况下动态连接到新的 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");