我正在尝试为我的应用程序创建一个Launcher程序,并且正在通过App
特征和main
方法来决定使用哪个。我在两者之间找到的唯一difference是:
(1)引用该对象的线程代码将阻塞,直到静态初始化完成。但是,因为扩展Application的对象的整个执行都是在静态初始化期间进行的,所以如果并发代码必须与封闭对象同步,它们将始终处于死锁状态。
在我的情况下,我有一个Launcher
基本上初始化一个Kafka
加载器对象,该对象继续运行kafka
轮询。以下是我的Launcher
特征:
trait Launcher extends LazyLogging {
val config: Config
val actorSystem: ActorSystem
val sourceMessagesType = config.getString("app.source.dataType")
val targetTopic = config.getString("app.kafka.targetTopic")
val targetTopicPartitions =config.getInt("app.kafka.targetTopicPartitions")
val routingManager = HashedPartitionRoutingManager(targetTopic, targetTopicPartitions)
logger.info(s"Initializing MorpheusStreamDataLoader for $sourceMessagesType type")
sourceMessagesType.toLowerCase match {
case "json" => JSonDataLoader(config, routingManager)
case "avro" => AvroDataLoader(config, routingManager)
case _ => throw new IllegalArgumentException
s"Messages of type ${sourceMessagesType.toLowerCase} are not supported.\n"
}
}
现在要启动我的应用程序,我试图找到最适合使用的方法,App
或main
方法。但是main
方法实现根本不起作用:
object ClientLauncher extends Launcher {
def main(args: Array[String]): Unit = {
override val config=ConfigFactory.load(args(0))
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
}
}
当我执行此操作时,override
修饰符override modifier is not allowed here
会出错。但是,如果我使用App
特征,它不会给我任何编译时错误。
object ClientLauncher extends App with Launcher {
override val config=ConfigFactory.load(args(0))
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
}
我阅读了几篇关于App
特征和main
的帖子后得到的信息是,除了使用App
特征时发生的延迟初始化之外,没有区别。为什么override
不适用于main
方法,适用于App
?我启动申请的最佳方式是什么?
答案 0 :(得分:1)
您需要将它们移出方法之外,以便它们是对象字段而不是局部变量。
object ClientLauncher extends Launcher {
override val config=ConfigFactory.load()
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
def main(args: Array[String]): Unit = {
/*code*/
}
}
虽然你不能以这种方式访问命令行参数或其他任何本地的参数。
如果您需要访问它并且不想扩展App,另一种方法是使用单独的类来扩展启动器。
class ClientLauncher(configFile: String) extends Launcher {
override val config=ConfigFactory.load(configFile)
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
}
object Main {
def main(args: Array[String]): Unit = {
new ClientLauncher(args(0))
}
}
或者将这些参数作为系统属性而不是命令行参数传递。
object ClientLauncher extends Launcher {
override val config=ConfigFactory.load(sys.props("configFile"))
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
def main(args: Array[String]): Unit = {
/*code*/
}
}
并在运行代码时传入系统属性
java -DconfigFile="config.conf" -jar myJar.jar