Java 在应用程序启动时动态触发对象方法
我有一个应用程序,应该生产汽车,并与他们一起经营。汽车对象创建是一个复杂的过程,所以我需要一个工厂为每种类型的汽车。我还希望用户能够提供他们自己的汽车类型和生产它们的工厂。这些车型和工厂应该作为jar插入到我的应用程序中(可能有比jar更好的方法,但我看不到) 我有了一个想法,制作一个普通的汽车工厂,它接受汽车的名称(“梅赛德斯”、“宝马”、“尼桑”等)作为论据。CarFactory有一个映射,其中每个名称都映射到自己的factory类。代码看起来像这样(很抱歉,我无法提供工作副本,因为我仍在对其进行评估,并且没有一个编译时没有错误的版本) knownCarTypes是可变的,因为我希望用户工厂在此地图上注册,提供他们负责的汽车类型以及工厂类的名称。从用户类来看,它是这样的Java 在应用程序启动时动态触发对象方法,java,scala,reflection,Java,Scala,Reflection,我有一个应用程序,应该生产汽车,并与他们一起经营。汽车对象创建是一个复杂的过程,所以我需要一个工厂为每种类型的汽车。我还希望用户能够提供他们自己的汽车类型和生产它们的工厂。这些车型和工厂应该作为jar插入到我的应用程序中(可能有比jar更好的方法,但我看不到) 我有了一个想法,制作一个普通的汽车工厂,它接受汽车的名称(“梅赛德斯”、“宝马”、“尼桑”等)作为论据。CarFactory有一个映射,其中每个名称都映射到自己的factory类。代码看起来像这样(很抱歉,我无法提供工作副本,因为我仍在对
class Mercedes extends Car
object MercedesFactory extends Factory {
def register() {
CarFactory.knownCarTypes("mercedes") = getClass
}
def create() = new Mercedes()
}
这是我的问题。我不知道如何触发用户工厂的register()方法。可能吗?有比我的方法更好的解决方案吗
我考虑为工厂创建公共trait,通过反射找到实现trait和trigger方法的所有加载类。但它看起来相当复杂。我希望这里可以使用一些设计模式或OOP技巧。你觉得怎么样
谢谢 如果我正确理解了您的问题,您所要做的就是从对象的“主体”调用register:
最后我通过反射使它工作起来。我迭代了指定路径上的所有JAR,找到了实现com.example.Factory trait的所有类,并触发了它们的register()方法。对于我使用的JAR检查和调用我遵循的对象方法,这里是最后的代码
import org.apache.commons.io.FileUtils
import org.clapper.classutil.{ClassFinder, ClassInfo}
import scala.collection.JavaConverters._
def triggerFactories() {
val jars = FileUtils.iterateFiles(new File("lib"), Array[String]("jar"), true).asScala.toList
val classes = ClassFinder(jars).getClasses
val factories = ClassFinder.concreteSubclasses("com.example.Factory", classes)
factories.foreach { (factory: ClassInfo) =>
companion[Factory](factory.name).register()
}
}
def companion[T](name: String)(implicit man: Manifest[T]): T =
Class.forName(name).getField("MODULE$").get(man.erasure).asInstanceOf[T]
这对我有用。这看起来很棘手,但我希望它不会破坏我的应用程序在未来的任何东西。如果有更好的方法,请发帖,我会重新接受答案。作为提示,如果您使用可变映射,则无需将其声明为变量。
+=
将对其进行适当的修改。哦。。你是对的。谢谢:)不幸的是,在我接触MercedesFactory对象之前(无论如何,通过调用其任何方法),它都不会调用对象体:(
object MercedesFactory extends Factory {
def register() {
CarFactory.knownCarTypes("mercedes") = getClass
}
register
def create() = new Mercedes()
}
import org.apache.commons.io.FileUtils
import org.clapper.classutil.{ClassFinder, ClassInfo}
import scala.collection.JavaConverters._
def triggerFactories() {
val jars = FileUtils.iterateFiles(new File("lib"), Array[String]("jar"), true).asScala.toList
val classes = ClassFinder(jars).getClasses
val factories = ClassFinder.concreteSubclasses("com.example.Factory", classes)
factories.foreach { (factory: ClassInfo) =>
companion[Factory](factory.name).register()
}
}
def companion[T](name: String)(implicit man: Manifest[T]): T =
Class.forName(name).getField("MODULE$").get(man.erasure).asInstanceOf[T]