代码之家  ›  专栏  ›  技术社区  ›  Michael

我怎样才能获得一个会话所需的所有全局变量?

  •  0
  • Michael  · 技术社区  · 6 年前

    我在用Drools,我在一个 KieSession .

    kieSession.setGlobal("foo", foo);
    kieSession.setGlobal("bar", bar);
    kieSession.setGlobal("baz", baz);
    //...
    

    我作为全局对象使用的每个对象都作为Springbean存在,因此我想到,如果我有一个全局对象的列表,我可以简单地“自动连接”会话。

    Map<String, Class<?>> globals = getGlobals(kieSession);
    globals.forEach((name, clazz) -> 
        kieSession.setGlobal(name, beanFactory.getBean(clazz))
    );
    

    有一个方法叫做 getGlobals 但它似乎只返回已经插入的全局变量。

    通过附加调试器,我可以看到这些值的映射存在于 KieBase ,我写了一个方法,通过反射得到它:

    @SuppressWarnings("unchecked")
    @SneakyThrows //Lombok turns the checked exceptions into unchecked
    private Map<String, Class<?>> getGlobals(final KieSession session)
    {
        final KieBase kieBase = session.getKieBase();
        final Field globals = kieBase.getClass().getDeclaredField("globals");
        globals.setAccessible(true);
        return (Map<String, Class<?>>) globals.get(kieBase);
    }
    

    这是可行的,但我宁愿不诉诸于反思,除非这是绝对必要的。

    有没有更好的方法来实现这一点?如果没有,是否有一个很好的理由来解释为什么这些信息被封装起来,以至于我通常无法访问它?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Michael    6 年前

    你可以从一个 KiePackage

    final Collection<KiePackage> kiePackages = kieSession.getKieBase().getKiePackages();
    for (KiePackage kiePackage : kiePackages)
    {
        final Collection<Global> globalVariables = kiePackage.getGlobalVariables();
        //...
    }