从版本3开始就没有使用Drools,但会尝试帮助。当你以这种方式加载类时(动态的,在运行时,不管你是否使用例如Class.forName()或Jodd),加载的类名都不能在代码中显式使用。我相信我们可以用下面的须藤代码,您第一次加载类,然后尝试使用其名称简化您的问题:
defineClass('Tire.class');
Tire tire = new Tire();
这显然因为轮胎类型不工作是不是可以在编译时:编译器不知道在执行过程中要加载的类型。
工作是让Tire实现一些接口(例如VehiclePart)。所以,那么你可以使用下面的须藤代码:
Class tireClass = defineClass('Tire.class');
VehiclePart tire = tireClass.newInstance();
System.out.println(tire.getPartName()); // prints 'tire' for example
那么也许你可以建立你的Drools在接口VehiclePart和getPartName()属性的规则。
附录
以上才有意义,只有当接口包括动态加载的类的所有属性。在大多数情况下,这不是一个有效的解决方案:动态加载的类不会共享属性。所以,这是另一种方法。
而不是使用显式类加载,可以通过'扩展'类加载器类路径来解决此问题。警告,这是一个黑客!
在Jodd中,有一种方法:ClassLoaderUtil.addFileToClassPath()可以在运行时向文件或路径添加类加载器。因此,下面是适用于我的步骤:
1)将所有动态创建的类放入某个根文件夹中,并考虑它们的包。例如,假设我们想要使用一个jodd.samples.TestBean类,该类有两个属性:号码(int)和值(字符串)。然后我们需要将它放入根目录/ jodd/samples文件夹中。
2)建立的所有动态类之后,扩展类加载器的路径:
ClassLoaderUtil.addFileToClassPath("root", ClassLoader.getSystemClassLoader());
3)负载类和创建KnowledgeBuilder之前创建它:
Class testBeanClass = Class.forName("jodd.samples.TestBean");
Object testBean = testBeanClass.newInstance();
4)在这一点上,你可以使用BeanUtils(来自Jodd,例如:)来操纵testBean实例的属性
5)创建Drools的东西并将insert insert testBean添加到会话中:
knowledgeSession.insert(testBean);
6)在规则文件中使用它:
import jodd.samples.TestBean;
rule "xxx"
when
$t: TestBean(number == 173)
then
System.out.println("!!!");
end
这为我工作。请注意,在第2步中,您可以尝试使用不同的类加载器,但您可能需要通过KnowledgeBuilderConfiguration(即PackageBuilderConfiguration)将它传递到KnowledgeBuilderFactory。
另一种解决方案
另一种解决方案是简单地将所有对象的属性复制到一张地图,及处理规则文件的地图。所以,你可以在步骤4中使用这样的:
Map map = new HashMap();
BeanTool.copy(testBean, map);
及更高版本(步骤#5)添加地图Drools的背景下,而不是bean实例。在这种情况下,使用defineClass()方法来明确定义每个类会更好。
我试着在规则文件中写入“import datatypes.Tire”。 (数据类型是轮胎类应该包含的包)。现在不是说不能解决轮胎问题,而是说不能解决轮胎问题。所以我解释这是因为Tyre正在被解析为一个包而不是一个类型,因此不能被导入。为什么会这样呢? –