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 个用途。
从这个问题开始:
作为我设计的一部分,我打算允许在 运行 时间修改数据库模式的操作。正如上述问题中所讨论的,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 个用途。