java - Spring Boot 在作为 Servlet 但不能作为命令行运行时可以连接到 Cassandra
问题描述
背景:我正在尝试为我们的 Cassandra 数据库建立一个基于代码的数据迁移系统。我没有大量的 Java 经验,但如果这是一个 .NET 项目,我会在同一个解决方案下将迁移设置为不同的项目。但是,根据其他更有经验的团队成员的指导,建议我将迁移包含在与应用程序的其余部分相同的包中(我可以接受)。还建议最简单的方法是通过 Web API 端点运行迁移(我对此持怀疑态度)。为了避免打开潜在的安全漏洞,我想我会尝试制作一个命令行实用程序来执行迁移。
我有一个 Spring Boot Web 应用程序,其入口点类如下所示:
@Configuration
@SpringBootApplication
@EnableAutoConfiguration
@EnableCaching
@EnableScheduling
public class MyApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApplication.class);
}
public static void main(String[] args) {
new MyApplication().configure(new SpringApplicationBuilder(MyApplication.class)).run(args);
}
}
但是,我正在尝试添加功能以通过命令行(例如java -jar MyApplication.jar migrate
)运行与此应用程序一起打包的几个迁移脚本,因此我添加了以下类:
@Configuration
@SpringBootApplication
@EnableAutoConfiguration
public class MigrationRunner implements CommandLineRunner {
@Autowired
Session session;
@Override
public void run(String[] args)
{
MigrationResources mr = new MigrationResources();
mr.addMigration(...);
mr.addMigration(...);
MigrationEngine.withSession(session).migrate(mr);
}
}
然后像这样更新我的入口点类:
// annotations
public class MyApplication extends SpringBootServletInitializer {
private final static String MIGRATE_COMMAND = "migrate";
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApplication.class);
}
public static void main(String[] args) {
if (args.length > 0 && args[0].equalsIgnoreCase(MIGRATE_COMMAND)) {
new SpringApplicationBuilder()
.sources(MigrationRunner.class)
.run(Arrays.copyOfRange(args, 1, args.length));
} else {
new MyApplication().configure(new SpringApplicationBuilder(MyApplication.class)).run(args);
}
}
}
问题是,当我使用migrate
arg 执行此操作时,Spring 会抛出此错误:
创建名称为“migrationRunner”的 bean 时出错:通过字段“会话”表达的不满足的依赖关系
在类路径资源 [org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfiguration.class] 中定义名称为“会话”的 bean 创建错误:调用 init 方法失败
尝试查询的所有主机都失败(尝试:server022/XX.YY.ZZ.022:9042 (com.datastax.driver.core.exceptions.TransportException: [server022/XX.YY.ZZ.022:9042] 连接已关闭), server022/XX.YY.ZZ.020:9042 (com.datastax.driver.core.exceptions.TransportException: [server020/XX.YY.ZZ.020:9042] 连接已关闭), server020/ XX.YY.ZZ.021:9042(com.datastax.driver.core.exceptions.TransportException: [server020/XX.YY.ZZ.021:9042] 连接已关闭))
migrate
在没有arg的情况下运行它仍然可以正常工作。我怀疑Spring 根本没有为这个 Cassandra 服务器获取正确的证书,即使它似乎正在获取所有其他配置属性(服务器名称、密钥空间等)
问题:如何制作一个同时具有命令行模式并且可以在两种模式下连接到配置的 Cassandra 服务器的 Spring Boot servlet?
解决方案
你需要做的就是,
@SpringBootApplication
public class MyApplication
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
您的应用程序过于复杂。如果您运行,默认情况下MyApplication.main
将在端口中运行。8080
奖金,如果您需要两者都从相同的class
.
@SpringBootApplication
public class MigrationRunner implements CommandLineRunner {
@Autowired
Session session;
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Override
public void run(String[] args)
{
MigrationResources mr = new MigrationResources();
mr.addMigration(...);
mr.addMigration(...);
MigrationEngine.withSession(session).migrate(mr);
}
}
推荐阅读
- python - Python - 在标签内调试 HTML 标签
- xaml - 如何阻止 Android ScrollViewer 将自身滚动到其第一个按钮子项
- mysql - 将大型 SQL Server 数据库转换为 MySQL 数据库
- binding - 如何通过代理解决选择器选择?
- python - 获取输入以仅接受来自字符串 Python 的内容
- java - java简单日期格式可以返回无效日期吗?
- verilog - 为什么逻辑右移在这段代码中表现得像算术右移?
- gatsby - 为页面构建静态 HTML 失败 - Gatsby 和 p5js
- node.js - Promise.all 提出“TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))”
- firebase - #flutter:配置“:cloud_firestore_web”时出现问题