Apache Cayenne:提供动态生成的项目定义

Apache Cayenne: supplying dynamically generated project definition

从这个问题开始:

作为我设计的一部分,我打算允许在 运行 时间修改数据库模式的操作。正如上述问题中所讨论的,Cayenne 似乎确实支持这一点。

我对如何在不使用文件系统的情况下将新项目定义提供给 ServerRuntime 很感兴趣。

查看源代码后,我似乎有两个选择:

(1) 实现自定义 classloader,将其设置为线程本地 class loader,并允许 Cayenne 使用 ClassLoaderResourceLocator 找到它。

(2) 实现一个自定义的ResourceLocator,并使用注入绑定。

很清楚我会怎么做 (1),但可以说 (2) 更简洁一些,因为它不依赖于 ClassLoaderResourceLocator 的行为。

(2) 是否合理,我该如何编码?

假设您的动态项目定义仍在 XML 中,自定义 ResourceLocator 绑定非常简单并且可能是可行的方法。所以如果你有自己的 XyzResourceLocator,你只需这样做:

// using lambda for the Module interface (assumes java 8)
ServerRuntime r = new ServerRuntime(
    "somelocation", 
     binder -> binder.bind(ResourceLocator.class)
                     .to(XyzResourceLocator.class));

XyzResourceLocator 的实现方式取决于动态生成的项目定义所在的位置。

另外,在查看源代码时我发现了一个小警告。 ResourceLocator 在不同的上下文中(IMO 错误地)用于加载一些内部 Cayenne XML 描述符。所以当你实现自己的定位器时,你可能需要做这样的检查:

if(name.endsWith("types.xml")) { .. revert to ClassLoaderResourceLocator ..}
else { .. use your own algorithm .. }

我们最终需要在 Cayenne 中分离这 2 个用途。